Merge branch 'master' into docker-dirlinks
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
# CODEOWNERS file
|
||||||
|
#
|
||||||
|
# This file is used to describe who owns what in this repository. This file does not
|
||||||
|
# replace `meta.maintainers` but is instead used for other things than derivations
|
||||||
|
# and modules, like documentation, package sets, and other assets.
|
||||||
|
#
|
||||||
|
# For documentation on this file, see https://help.github.com/articles/about-codeowners/
|
||||||
|
# Mentioned users will get code review requests.
|
||||||
|
|
||||||
|
# This file
|
||||||
|
/.github/CODEOWNERS @edolstra
|
||||||
|
|
||||||
|
# Boostraping and core infra
|
||||||
|
/pkgs/stdenv @edolstra
|
||||||
|
/pkgs/build-support/cc-wrapper @edolstra
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
/lib @edolstra @nbp
|
||||||
|
|
||||||
|
# Nixpkgs Internals
|
||||||
|
/default.nix @nbp
|
||||||
|
/pkgs/top-level/default.nix @nbp
|
||||||
|
/pkgs/top-level/impure.nix @nbp
|
||||||
|
/pkgs/top-level/stage.nix @nbp
|
||||||
|
|
||||||
|
# NixOS Internals
|
||||||
|
/nixos/default.nix @nbp
|
||||||
|
/nixos/lib/from-env.nix @nbp
|
||||||
|
/nixos/lib/eval-config.nix @nbp
|
||||||
|
/nixos/doc/manual/configuration/abstractions.xml @nbp
|
||||||
|
/nixos/doc/manual/configuration/config-file.xml @nbp
|
||||||
|
/nixos/doc/manual/configuration/config-syntax.xml @nbp
|
||||||
|
/nixos/doc/manual/configuration/modularity.xml @nbp
|
||||||
|
/nixos/doc/manual/development/assertions.xml @nbp
|
||||||
|
/nixos/doc/manual/development/meta-attributes.xml @nbp
|
||||||
|
/nixos/doc/manual/development/option-declarations.xml @nbp
|
||||||
|
/nixos/doc/manual/development/option-def.xml @nbp
|
||||||
|
/nixos/doc/manual/development/option-types.xml @nbp
|
||||||
|
/nixos/doc/manual/development/replace-modules.xml @nbp
|
||||||
|
/nixos/doc/manual/development/writing-modules.xml @nbp
|
||||||
|
/nixos/doc/manual/man-nixos-option.xml @nbp
|
||||||
|
/nixos/modules/installer/tools/nixos-option.sh @nbp
|
||||||
|
|
||||||
|
# Python-related code and docs
|
||||||
|
/pkgs/top-level/python-packages.nix @FRidh
|
||||||
|
/pkgs/development/interpreters/python @FRidh
|
||||||
|
/pkgs/development/python-modules @FRidh
|
||||||
|
/doc/languages-frameworks/python.md @FRidh
|
||||||
|
|
||||||
|
# Haskell
|
||||||
|
/pkgs/development/compilers/ghc @peti
|
||||||
|
/pkgs/development/haskell-modules @peti
|
||||||
|
/pkgs/development/haskell-modules/default.nix @peti
|
||||||
|
/pkgs/development/haskell-modules/generic-builder.nix @peti
|
||||||
|
/pkgs/development/haskell-modules/hoogle.nix @peti
|
||||||
|
|
||||||
|
# R
|
||||||
|
/pkgs/applications/science/math/R @peti
|
||||||
|
/pkgs/development/r-modules @peti
|
||||||
|
|
||||||
|
# Ruby
|
||||||
|
/pkgs/development/interpreters/ruby @zimbatm
|
||||||
|
/pkgs/development/ruby-modules @zimbatm
|
||||||
|
|
||||||
|
# Darwin-related
|
||||||
|
/pkgs/stdenv/darwin @NixOS/darwin-maintainers
|
||||||
|
/pkgs/os-specific/darwin @NixOS/darwin-maintainers
|
||||||
|
|
||||||
|
# Beam-related (Erlang, Elixir, LFE, etc)
|
||||||
|
/pkgs/development/beam-modules @gleber
|
||||||
|
/pkgs/development/interpreters/erlang @gleber
|
||||||
|
/pkgs/development/interpreters/lfe @gleber
|
||||||
|
/pkgs/development/interpreters/elixir @gleber
|
||||||
|
/pkgs/development/tools/build-managers/rebar @gleber
|
||||||
|
/pkgs/development/tools/build-managers/rebar3 @gleber
|
||||||
|
/pkgs/development/tools/erlang @gleber
|
||||||
|
|
||||||
|
# Jetbrains
|
||||||
|
/pkgs/applications/editors/jetbrains @edwtjo
|
||||||
|
|
||||||
|
# Eclipse
|
||||||
|
/pkgs/applications/editors/eclipse @rycee
|
||||||
+11
-8
@@ -15,7 +15,7 @@ under the terms of [COPYING](../COPYING), which is an MIT-like license.
|
|||||||
* Format the commits in the following way:
|
* Format the commits in the following way:
|
||||||
|
|
||||||
```
|
```
|
||||||
(pkg-name | service-name): (from -> to | init at version | refactor | etc)
|
(pkg-name | nixos/<module>): (from -> to | init at version | refactor | etc)
|
||||||
|
|
||||||
(Motivation for change. Additional information.)
|
(Motivation for change. Additional information.)
|
||||||
```
|
```
|
||||||
@@ -23,20 +23,23 @@ under the terms of [COPYING](../COPYING), which is an MIT-like license.
|
|||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
* nginx: init at 2.0.1
|
* nginx: init at 2.0.1
|
||||||
* firefox: 3.0 -> 3.1.1
|
* firefox: 54.0.1 -> 55.0
|
||||||
* hydra service: add bazBaz option
|
* nixos/hydra: add bazBaz option
|
||||||
|
|
||||||
Dual baz behavior is needed to do foo.
|
Dual baz behavior is needed to do foo.
|
||||||
* nginx service: refactor config generation
|
* nixos/nginx: refactor config generation
|
||||||
|
|
||||||
The old config generation system used impure shell scripts and could break in specific circumstances (see #1234).
|
The old config generation system used impure shell scripts and could break in specific circumstances (see #1234).
|
||||||
|
|
||||||
* `meta.description` should:
|
* `meta.description` should:
|
||||||
* Be capitalized
|
* Be capitalized.
|
||||||
* Not start with the package name
|
* Not start with the package name.
|
||||||
* Not have a dot at the end
|
* Not have a period at the end.
|
||||||
|
* `meta.license` must be set and fit the upstream license.
|
||||||
|
* If there is no upstream license, `meta.license` should default to `stdenv.lib.licenses.unfree`.
|
||||||
|
* `meta.maintainers` must be set.
|
||||||
|
|
||||||
See the nixpkgs manual for more details on how to [Submit changes to nixpkgs](https://nixos.org/nixpkgs/manual/#chap-submitting-changes).
|
See the nixpkgs manual for more details on [standard meta-attributes](https://nixos.org/nixpkgs/manual/#sec-standard-meta-attributes) and on how to [submit changes to nixpkgs](https://nixos.org/nixpkgs/manual/#chap-submitting-changes).
|
||||||
|
|
||||||
## Writing good commit messages
|
## Writing good commit messages
|
||||||
|
|
||||||
|
|||||||
@@ -11,3 +11,4 @@
|
|||||||
* System: (NixOS: `nixos-version`, Ubuntu/Fedora: `lsb_release -a`, ...)
|
* System: (NixOS: `nixos-version`, Ubuntu/Fedora: `lsb_release -a`, ...)
|
||||||
* Nix version: (run `nix-env --version`)
|
* Nix version: (run `nix-env --version`)
|
||||||
* Nixpkgs version: (run `nix-instantiate --eval '<nixpkgs>' -A lib.nixpkgsVersion`)
|
* Nixpkgs version: (run `nix-instantiate --eval '<nixpkgs>' -A lib.nixpkgsVersion`)
|
||||||
|
* Sandboxing enabled: (run `grep build-use-sandbox /etc/nix/nix.conf`)
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
|
|
||||||
###### Things done
|
###### Things done
|
||||||
|
|
||||||
- [ ] Tested using sandboxing
|
<!-- Please check what applies. Note that these are not hard requirements but merely serve as information for reviewers. -->
|
||||||
([nix.useSandbox](http://nixos.org/nixos/manual/options.html#opt-nix.useSandbox) on NixOS,
|
|
||||||
or option `build-use-sandbox` in [`nix.conf`](http://nixos.org/nix/manual/#sec-conf-file)
|
- [ ] Tested using sandboxing ([nix.useSandbox](http://nixos.org/nixos/manual/options.html#opt-nix.useSandbox) on NixOS, or option `build-use-sandbox` in [`nix.conf`](http://nixos.org/nix/manual/#sec-conf-file) on non-NixOS)
|
||||||
on non-NixOS)
|
|
||||||
- Built on platform(s)
|
- Built on platform(s)
|
||||||
- [ ] NixOS
|
- [ ] NixOS
|
||||||
- [ ] macOS
|
- [ ] macOS
|
||||||
- [ ] Linux
|
- [ ] other Linux distributions
|
||||||
|
- [ ] Tested via one or more NixOS test(s) if existing and applicable for the change (look inside [nixos/tests](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests))
|
||||||
- [ ] Tested compilation of all pkgs that depend on this change using `nix-shell -p nox --run "nox-review wip"`
|
- [ ] Tested compilation of all pkgs that depend on this change using `nix-shell -p nox --run "nox-review wip"`
|
||||||
- [ ] Tested execution of all binary files (usually in `./result/bin/`)
|
- [ ] Tested execution of all binary files (usually in `./result/bin/`)
|
||||||
- [ ] Fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md).
|
- [ ] Fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md).
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"userBlacklist": [
|
|
||||||
"civodul",
|
|
||||||
"jhasse",
|
|
||||||
"shlevy",
|
|
||||||
"bbenoist"
|
|
||||||
],
|
|
||||||
"alwaysNotifyForPaths": [
|
|
||||||
{ "name": "FRidh", "files": ["pkgs/top-level/python-packages.nix", "pkgs/development/interpreters/python/*", "pkgs/development/python-modules/*" ] },
|
|
||||||
{ "name": "LnL7", "files": ["pkgs/stdenv/darwin/*", "pkgs/os-specific/darwin/*"] },
|
|
||||||
{ "name": "copumpkin", "files": ["pkgs/stdenv/darwin/*", "pkgs/os-specific/darwin/apple-source-releases/*"] }
|
|
||||||
],
|
|
||||||
"fileBlacklist": ["pkgs/top-level/all-packages.nix"]
|
|
||||||
}
|
|
||||||
+7
-3
@@ -12,20 +12,24 @@ matrix:
|
|||||||
script:
|
script:
|
||||||
- ./maintainers/scripts/travis-nox-review-pr.sh nixpkgs-verify nixpkgs-manual nixpkgs-tarball nixpkgs-unstable
|
- ./maintainers/scripts/travis-nox-review-pr.sh nixpkgs-verify nixpkgs-manual nixpkgs-tarball nixpkgs-unstable
|
||||||
- ./maintainers/scripts/travis-nox-review-pr.sh nixos-options nixos-manual
|
- ./maintainers/scripts/travis-nox-review-pr.sh nixos-options nixos-manual
|
||||||
|
env:
|
||||||
|
- BUILD_TYPE="Test Nixpkgs evaluation & NixOS manual build"
|
||||||
- os: linux
|
- os: linux
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
before_script:
|
before_script:
|
||||||
- sudo mount -o remount,exec,size=2G,mode=755 /run/user
|
- sudo mount -o remount,exec,size=2G,mode=755 /run/user
|
||||||
script: ./maintainers/scripts/travis-nox-review-pr.sh nox pr
|
script: ./maintainers/scripts/travis-nox-review-pr.sh nox pr
|
||||||
|
env:
|
||||||
|
- BUILD_TYPE="Build affected packages (Linux)"
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode7.3
|
osx_image: xcode7.3
|
||||||
script: ./maintainers/scripts/travis-nox-review-pr.sh nox pr
|
script: ./maintainers/scripts/travis-nox-review-pr.sh nox pr
|
||||||
|
env:
|
||||||
|
- BUILD_TYPE="Build affected packages (macOS)"
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- GITHUB_TOKEN=5edaaf1017f691ed34e7f80878f8f5fbd071603f
|
- GITHUB_TOKEN=5edaaf1017f691ed34e7f80878f8f5fbd071603f
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email:
|
email: false
|
||||||
on_success: never
|
|
||||||
on_failure: change
|
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ build daemon as so-called channels. To get channel information via git, add
|
|||||||
```
|
```
|
||||||
|
|
||||||
For stability and maximum binary package support, it is recommended to maintain
|
For stability and maximum binary package support, it is recommended to maintain
|
||||||
custom changes on top of one of the channels, e.g. `nixos-17.03` for the latest
|
custom changes on top of one of the channels, e.g. `nixos-17.09` for the latest
|
||||||
release and `nixos-unstable` for the latest successful build of master:
|
release and `nixos-unstable` for the latest successful build of master:
|
||||||
|
|
||||||
```
|
```
|
||||||
% git remote update channels
|
% git remote update channels
|
||||||
% git rebase channels/nixos-17.03
|
% git rebase channels/nixos-17.09
|
||||||
```
|
```
|
||||||
|
|
||||||
For pull-requests, please rebase onto nixpkgs `master`.
|
For pull-requests, please rebase onto nixpkgs `master`.
|
||||||
@@ -30,13 +30,13 @@ For pull-requests, please rebase onto nixpkgs `master`.
|
|||||||
* [Documentation (Nix Expression Language chapter)](https://nixos.org/nix/manual/#ch-expression-language)
|
* [Documentation (Nix Expression Language chapter)](https://nixos.org/nix/manual/#ch-expression-language)
|
||||||
* [Manual (How to write packages for Nix)](https://nixos.org/nixpkgs/manual/)
|
* [Manual (How to write packages for Nix)](https://nixos.org/nixpkgs/manual/)
|
||||||
* [Manual (NixOS)](https://nixos.org/nixos/manual/)
|
* [Manual (NixOS)](https://nixos.org/nixos/manual/)
|
||||||
* [Nix Wiki](https://nixos.org/wiki/) (deprecated, see milestone ["Move the Wiki!"](https://github.com/NixOS/nixpkgs/issues?q=is%3Aopen+is%3Aissue+milestone%3A%22Move+the+wiki%21%22))
|
* [Community maintained wiki](https://nixos.wiki/)
|
||||||
* [Continuous package builds for unstable/master](https://hydra.nixos.org/jobset/nixos/trunk-combined)
|
* [Continuous package builds for unstable/master](https://hydra.nixos.org/jobset/nixos/trunk-combined)
|
||||||
* [Continuous package builds for 17.03 release](https://hydra.nixos.org/jobset/nixos/release-17.03)
|
* [Continuous package builds for 17.09 release](https://hydra.nixos.org/jobset/nixos/release-17.09)
|
||||||
* [Tests for unstable/master](https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
|
* [Tests for unstable/master](https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
|
||||||
* [Tests for 17.03 release](https://hydra.nixos.org/job/nixos/release-17.03/tested#tabs-constituents)
|
* [Tests for 17.09 release](https://hydra.nixos.org/job/nixos/release-17.09/tested#tabs-constituents)
|
||||||
|
|
||||||
Communication:
|
Communication:
|
||||||
|
|
||||||
* [Mailing list](http://lists.science.uu.nl/mailman/listinfo/nix-dev)
|
* [Mailing list](https://groups.google.com/forum/#!forum/nix-devel)
|
||||||
* [IRC - #nixos on freenode.net](irc://irc.freenode.net/#nixos)
|
* [IRC - #nixos on freenode.net](irc://irc.freenode.net/#nixos)
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ bound to the variable name <varname>e2fsprogs</varname> in
|
|||||||
dash) — e.g., <literal>"hello-0.3.1rc2"</literal>.</para></listitem>
|
dash) — e.g., <literal>"hello-0.3.1rc2"</literal>.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>If a package is not a release but a commit from a repository, then
|
<listitem><para>If a package is not a release but a commit from a repository, then
|
||||||
the version part of the name <emphasis>must</emphasis> be the date of that
|
the version part of the name <emphasis>must</emphasis> be the date of that
|
||||||
(fetched) commit. The date must be in <literal>"YYYY-MM-DD"</literal> format.
|
(fetched) commit. The date must be in <literal>"YYYY-MM-DD"</literal> format.
|
||||||
Also append <literal>"unstable"</literal> to the name - e.g.,
|
Also append <literal>"unstable"</literal> to the name - e.g.,
|
||||||
<literal>"pkgname-unstable-2014-09-23"</literal>.</para></listitem>
|
<literal>"pkgname-unstable-2014-09-23"</literal>.</para></listitem>
|
||||||
@@ -365,7 +365,7 @@ splitting up an existing category.</para>
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>If it’s a (set of) <emphasis>tool(s)</emphasis>:</term>
|
<term>If it’s a (set of) <emphasis>tool(s)</emphasis>:</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>(A tool is a relatively small program, especially one intented
|
<para>(A tool is a relatively small program, especially one intended
|
||||||
to be used non-interactively.)</para>
|
to be used non-interactively.)</para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@@ -456,7 +456,7 @@ splitting up an existing category.</para>
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>If it’s a <emphasis>window manager</emphasis>:</term>
|
<term>If it’s a <emphasis>window manager</emphasis>:</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para><filename>applications/window-managers</filename> (e.g. <filename>awesome</filename>, <filename>compiz</filename>, <filename>stumpwm</filename>)</para>
|
<para><filename>applications/window-managers</filename> (e.g. <filename>awesome</filename>, <filename>stumpwm</filename>)</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@@ -608,7 +608,7 @@ evaluate correctly.</para>
|
|||||||
</section>
|
</section>
|
||||||
<section xml:id="sec-sources"><title>Fetching Sources</title>
|
<section xml:id="sec-sources"><title>Fetching Sources</title>
|
||||||
<para>There are multiple ways to fetch a package source in nixpkgs. The
|
<para>There are multiple ways to fetch a package source in nixpkgs. The
|
||||||
general guidline is that you should package sources with a high degree of
|
general guideline is that you should package sources with a high degree of
|
||||||
availability. Right now there is only one fetcher which has mirroring
|
availability. Right now there is only one fetcher which has mirroring
|
||||||
support and that is <literal>fetchurl</literal>. Note that you should also
|
support and that is <literal>fetchurl</literal>. Note that you should also
|
||||||
prefer protocols which have a corresponding proxy environment variable.
|
prefer protocols which have a corresponding proxy environment variable.
|
||||||
@@ -661,9 +661,9 @@ src = fetchFromGitHub {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="sec-patches"><title>Patches</title>
|
<section xml:id="sec-patches"><title>Patches</title>
|
||||||
<para>Only patches that are unique to <literal>nixpkgs</literal> should be
|
<para>Only patches that are unique to <literal>nixpkgs</literal> should be
|
||||||
included in <literal>nixpkgs</literal> source.</para>
|
included in <literal>nixpkgs</literal> source.</para>
|
||||||
<para>Patches available online should be retrieved using
|
<para>Patches available online should be retrieved using
|
||||||
<literal>fetchpatch</literal>.</para>
|
<literal>fetchpatch</literal>.</para>
|
||||||
<para>
|
<para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
|
|||||||
+218
-1
@@ -55,6 +55,10 @@ configuration file located at
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>Note that we are not able to test or build unfree software on Hydra
|
||||||
|
due to policy. Most unfree licenses prohibit us from either executing or
|
||||||
|
distributing the software.</para>
|
||||||
|
|
||||||
<section xml:id="sec-allow-broken">
|
<section xml:id="sec-allow-broken">
|
||||||
<title>Installing broken packages</title>
|
<title>Installing broken packages</title>
|
||||||
|
|
||||||
@@ -227,7 +231,7 @@ packages via <literal>packageOverrides</literal></title>
|
|||||||
|
|
||||||
<para>You can define a function called
|
<para>You can define a function called
|
||||||
<varname>packageOverrides</varname> in your local
|
<varname>packageOverrides</varname> in your local
|
||||||
<filename>~/.config/nixpkgs/config.nix</filename> to overide nix packages. It
|
<filename>~/.config/nixpkgs/config.nix</filename> to override nix packages. It
|
||||||
must be a function that takes pkgs as an argument and return modified
|
must be a function that takes pkgs as an argument and return modified
|
||||||
set of packages.
|
set of packages.
|
||||||
|
|
||||||
@@ -243,5 +247,218 @@ set of packages.
|
|||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-declarative-package-management">
|
||||||
|
<title>Declarative Package Management</title>
|
||||||
|
|
||||||
|
<section xml:id="sec-building-environment">
|
||||||
|
<title>Build an environment</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Using <literal>packageOverrides</literal>, it is possible to manage
|
||||||
|
packages declaratively. This means that we can list all of our desired
|
||||||
|
packages within a declarative Nix expression. For example, to have
|
||||||
|
<literal>aspell</literal>, <literal>bc</literal>,
|
||||||
|
<literal>ffmpeg</literal>, <literal>coreutils</literal>,
|
||||||
|
<literal>gdb</literal>, <literal>nixUnstable</literal>,
|
||||||
|
<literal>emscripten</literal>, <literal>jq</literal>,
|
||||||
|
<literal>nox</literal>, and <literal>silver-searcher</literal>, we could
|
||||||
|
use the following in <filename>~/.config/nixpkgs/config.nix</filename>:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
{
|
||||||
|
packageOverrides = pkgs: with pkgs; {
|
||||||
|
myPackages = pkgs.buildEnv {
|
||||||
|
name = "my-packages";
|
||||||
|
paths = [ aspell bc coreutils gdb ffmpeg nixUnstable emscripten jq nox silver-searcher ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To install it into our environment, you can just run <literal>nix-env -iA
|
||||||
|
nixpkgs.myPackages</literal>. If you want to load the packages to be built
|
||||||
|
from a working copy of <literal>nixpkgs</literal> you just run
|
||||||
|
<literal>nix-env -f. -iA myPackages</literal>. To explore what's been
|
||||||
|
installed, just look through <filename>~/.nix-profile/</filename>. You can
|
||||||
|
see that a lot of stuff has been installed. Some of this stuff is useful
|
||||||
|
some of it isn't. Let's tell Nixpkgs to only link the stuff that we want:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
{
|
||||||
|
packageOverrides = pkgs: with pkgs; {
|
||||||
|
myPackages = pkgs.buildEnv {
|
||||||
|
name = "my-packages";
|
||||||
|
paths = [ aspell bc coreutils gdb ffmpeg nixUnstable emscripten jq nox silver-searcher ];
|
||||||
|
pathsToLink = [ "/share" "/bin" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<literal>pathsToLink</literal> tells Nixpkgs to only link the paths listed
|
||||||
|
which gets rid of the extra stuff in the profile.
|
||||||
|
<filename>/bin</filename> and <filename>/share</filename> are good
|
||||||
|
defaults for a user environment, getting rid of the clutter. If you are
|
||||||
|
running on Nix on MacOS, you may want to add another path as well,
|
||||||
|
<filename>/Applications</filename>, that makes GUI apps available.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-getting-documentation">
|
||||||
|
<title>Getting documentation</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
After building that new environment, look through
|
||||||
|
<filename>~/.nix-profile</filename> to make sure everything is there that
|
||||||
|
we wanted. Discerning readers will note that some files are missing. Look
|
||||||
|
inside <filename>~/.nix-profile/share/man/man1/</filename> to verify this.
|
||||||
|
There are no man pages for any of the Nix tools! This is because some
|
||||||
|
packages like Nix have multiple outputs for things like documentation (see
|
||||||
|
section 4). Let's make Nix install those as well.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
{
|
||||||
|
packageOverrides = pkgs: with pkgs; {
|
||||||
|
myPackages = pkgs.buildEnv {
|
||||||
|
name = "my-packages";
|
||||||
|
paths = [ aspell bc coreutils ffmpeg nixUnstable emscripten jq nox silver-searcher ];
|
||||||
|
pathsToLink = [ "/share/man" "/share/doc" /bin" ];
|
||||||
|
extraOutputsToInstall = [ "man" "doc" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
This provides us with some useful documentation for using our packages.
|
||||||
|
However, if we actually want those manpages to be detected by man, we need
|
||||||
|
to set up our environment. This can also be managed within Nix
|
||||||
|
expressions.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
{
|
||||||
|
packageOverrides = pkgs: with pkgs; rec {
|
||||||
|
myProfile = writeText "my-profile" ''
|
||||||
|
export PATH=$HOME/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
|
export MANPATH=$HOME/.nix-profile/share/man:/nix/var/nix/profiles/default/share/man:/usr/share/man
|
||||||
|
'';
|
||||||
|
myPackages = pkgs.buildEnv {
|
||||||
|
name = "my-packages";
|
||||||
|
paths = [
|
||||||
|
(runCommand "profile" {} ''
|
||||||
|
mkdir -p $out/etc/profile.d
|
||||||
|
cp ${myProfile} $out/etc/profile.d/my-profile.sh
|
||||||
|
'')
|
||||||
|
aspell
|
||||||
|
bc
|
||||||
|
coreutils
|
||||||
|
ffmpeg
|
||||||
|
man
|
||||||
|
nixUnstable
|
||||||
|
emscripten
|
||||||
|
jq
|
||||||
|
nox
|
||||||
|
silver-searcher
|
||||||
|
];
|
||||||
|
pathsToLink = [ "/share/man" "/share/doc" /bin" "/etc" ];
|
||||||
|
extraOutputsToInstall = [ "man" "doc" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
For this to work fully, you must also have this script sourced when you
|
||||||
|
are logged in. Try adding something like this to your
|
||||||
|
<filename>~/.profile</filename> file:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
#!/bin/sh
|
||||||
|
if [ -d $HOME/.nix-profile/etc/profile.d ]; then
|
||||||
|
for i in $HOME/.nix-profile/etc/profile.d/*.sh; do
|
||||||
|
if [ -r $i ]; then
|
||||||
|
. $i
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Now just run <literal>source $HOME/.profile</literal> and you can starting
|
||||||
|
loading man pages from your environent.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-gnu-info-setup">
|
||||||
|
<title>GNU info setup</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Configuring GNU info is a little bit trickier than man pages. To work
|
||||||
|
correctly, info needs a database to be generated. This can be done with
|
||||||
|
some small modifications to our environment scripts.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
{
|
||||||
|
packageOverrides = pkgs: with pkgs; rec {
|
||||||
|
myProfile = writeText "my-profile" ''
|
||||||
|
export PATH=$HOME/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
|
export MANPATH=$HOME/.nix-profile/share/man:/nix/var/nix/profiles/default/share/man:/usr/share/man
|
||||||
|
export INFOPATH=$HOME/.nix-profile/share/info:/nix/var/nix/profiles/default/share/info:/usr/share/info
|
||||||
|
'';
|
||||||
|
myPackages = pkgs.buildEnv {
|
||||||
|
name = "my-packages";
|
||||||
|
paths = [
|
||||||
|
(runCommand "profile" {} ''
|
||||||
|
mkdir -p $out/etc/profile.d
|
||||||
|
cp ${myProfile} $out/etc/profile.d/my-profile.sh
|
||||||
|
'')
|
||||||
|
aspell
|
||||||
|
bc
|
||||||
|
coreutils
|
||||||
|
ffmpeg
|
||||||
|
man
|
||||||
|
nixUnstable
|
||||||
|
emscripten
|
||||||
|
jq
|
||||||
|
nox
|
||||||
|
silver-searcher
|
||||||
|
texinfoInteractive
|
||||||
|
];
|
||||||
|
pathsToLink = [ "/share/man" "/share/doc" "/share/info" "/bin" "/etc" ];
|
||||||
|
extraOutputsToInstall = [ "man" "doc" "info" ];
|
||||||
|
postBuild = ''
|
||||||
|
if [ -x $out/bin/install-info -a -w $out/share/info ]; then
|
||||||
|
shopt -s nullglob
|
||||||
|
for i in $out/share/info/*.info $out/share/info/*.info.gz; do
|
||||||
|
$out/bin/install-info $i $out/share/info/dir
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<literal>postBuild</literal> tells Nixpkgs to run a command after building
|
||||||
|
the environment. In this case, <literal>install-info</literal> adds the
|
||||||
|
installed info pages to <literal>dir</literal> which is GNU info's default
|
||||||
|
root node. Note that <literal>texinfoInteractive</literal> is added to the
|
||||||
|
environment to give the <literal>install-info</literal> command.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|||||||
+57
-20
@@ -30,15 +30,16 @@
|
|||||||
<section>
|
<section>
|
||||||
<title>Platform parameters</title>
|
<title>Platform parameters</title>
|
||||||
<para>
|
<para>
|
||||||
The three GNU Autoconf platforms, <wordasword>build</wordasword>, <wordasword>host</wordasword>, and <wordasword>cross</wordasword>, are historically the result of much confusion.
|
The three GNU Autoconf platforms, <wordasword>build</wordasword>, <wordasword>host</wordasword>, and <wordasword>target</wordasword>, are historically the result of much confusion.
|
||||||
<link xlink:href="https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html" /> clears this up somewhat but there is more to be said.
|
<link xlink:href="https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html" /> clears this up somewhat but there is more to be said.
|
||||||
An important advice to get out the way is, unless you are packaging a compiler or other build tool, just worry about the build and host platforms.
|
An important advice to get out the way is, unless you are packaging a compiler or other build tool, just worry about the build and host platforms.
|
||||||
Dealing with just two platforms usually better matches people's preconceptions, and in this case is completely correct.
|
Dealing with just two platforms usually better matches people's preconceptions, and in this case is completely correct.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
In Nixpkgs, these three platforms are defined as attribute sets under the names <literal>buildPlatform</literal>, <literal>hostPlatform</literal>, and <literal>targetPlatform</literal>.
|
In Nixpkgs, these three platforms are defined as attribute sets under the names <literal>buildPlatform</literal>, <literal>hostPlatform</literal>, and <literal>targetPlatform</literal>.
|
||||||
All three are always defined at the top level, so one can get at them just like a dependency in a function that is imported with <literal>callPackage</literal>:
|
All three are always defined as attributes in the standard environment, and at the top level. That means one can get at them just like a dependency in a function that is imported with <literal>callPackage</literal>:
|
||||||
<programlisting>{ stdenv, buildPlatform, hostPlatform, fooDep, barDep, .. }: ...</programlisting>
|
<programlisting>{ stdenv, buildPlatform, hostPlatform, fooDep, barDep, .. }: ...buildPlatform...</programlisting>, or just off <varname>stdenv</varname>:
|
||||||
|
<programlisting>{ stdenv, fooDep, barDep, .. }: ...stdenv.buildPlatform...</programlisting>.
|
||||||
</para>
|
</para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@@ -62,8 +63,8 @@
|
|||||||
The "target platform" is black sheep.
|
The "target platform" is black sheep.
|
||||||
The other two intrinsically apply to all compiled software—or any build process with a notion of "build-time" followed by "run-time".
|
The other two intrinsically apply to all compiled software—or any build process with a notion of "build-time" followed by "run-time".
|
||||||
The target platform only applies to programming tools, and even then only is a good for for some of them.
|
The target platform only applies to programming tools, and even then only is a good for for some of them.
|
||||||
Briefly, GCC, Binutils, GHC, and certain other tools are written in such a way such that a single build can only compiler code for a single platform.
|
Briefly, GCC, Binutils, GHC, and certain other tools are written in such a way such that a single build can only compile code for a single platform.
|
||||||
Thus, when building them, one must think ahead about what platforms they wish to use the tool to produce machine code for, and build binaries for each.
|
Thus, when building them, one must think ahead about which platforms they wish to use the tool to produce machine code for, and build binaries for each.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
There is no fundamental need to think about the target ahead of time like this.
|
There is no fundamental need to think about the target ahead of time like this.
|
||||||
@@ -79,13 +80,9 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
<note><para>
|
|
||||||
If you dig around nixpkgs, you may notice there is also <varname>stdenv.cross</varname>.
|
|
||||||
This field defined as <varname>hostPlatform</varname> when the host and build platforms differ, but otherwise not defined at all.
|
|
||||||
This field is obsolete and will soon disappear—please do not use it.
|
|
||||||
</para></note>
|
|
||||||
<para>
|
<para>
|
||||||
The exact scheme these fields is a bit ill-defined due to a long and convoluted evolution, but this is slowly being cleaned up.
|
The exact schema these fields follow is a bit ill-defined due to a long and convoluted evolution, but this is slowly being cleaned up.
|
||||||
|
You can see examples of ones used in practice in <literal>lib.systems.examples</literal>; note how they are not all very consistent.
|
||||||
For now, here are few fields can count on them containing:
|
For now, here are few fields can count on them containing:
|
||||||
</para>
|
</para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
@@ -118,8 +115,27 @@
|
|||||||
This is a nix representation of a parsed LLVM target triple with white-listed components.
|
This is a nix representation of a parsed LLVM target triple with white-listed components.
|
||||||
This can be specified directly, or actually parsed from the <varname>config</varname>.
|
This can be specified directly, or actually parsed from the <varname>config</varname>.
|
||||||
[Technically, only one need be specified and the others can be inferred, though the precision of inference may not be very good.]
|
[Technically, only one need be specified and the others can be inferred, though the precision of inference may not be very good.]
|
||||||
See <literal>lib.systems.parse</literal> for the exact representation, along with some <literal>is*</literal>predicates.
|
See <literal>lib.systems.parse</literal> for the exact representation.
|
||||||
These predicates are superior to the ones in <varname>stdenv</varname> as they aren't tied to the build platform (host, as previously discussed, would be a saner default).
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>libc</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This is a string identifying the standard C library used.
|
||||||
|
Valid identifiers include "glibc" for GNU libc, "libSystem" for Darwin's Libsystem, and "uclibc" for µClibc.
|
||||||
|
It should probably be refactored to use the module system, like <varname>parse</varname>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>is*</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
These predicates are defined in <literal>lib.systems.inspect</literal>, and slapped on every platform.
|
||||||
|
They are superior to the ones in <varname>stdenv</varname> as they force the user to be explicit about which platform they are inspecting.
|
||||||
|
Please use these instead of those.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@@ -128,7 +144,7 @@
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
This is, quite frankly, a dumping ground of ad-hoc settings (it's an attribute set).
|
This is, quite frankly, a dumping ground of ad-hoc settings (it's an attribute set).
|
||||||
See <literal>lib.systems.platforms</literal> for examples—there's hopefully one in there that will work verbatim for each platform one is working.
|
See <literal>lib.systems.platforms</literal> for examples—there's hopefully one in there that will work verbatim for each platform that is working.
|
||||||
Please help us triage these flags and give them better homes!
|
Please help us triage these flags and give them better homes!
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@@ -158,15 +174,20 @@
|
|||||||
The depending package's target platform is unconstrained by the sliding window principle, which makes sense in that one can in principle build cross compilers targeting arbitrary platforms.
|
The depending package's target platform is unconstrained by the sliding window principle, which makes sense in that one can in principle build cross compilers targeting arbitrary platforms.
|
||||||
</para></note>
|
</para></note>
|
||||||
<para>
|
<para>
|
||||||
How does this work in practice? Nixpkgs is now structured so that build-time dependencies are taken from from <varname>buildPackages</varname>, whereas run-time dependencies are taken from the top level attribute set.
|
How does this work in practice? Nixpkgs is now structured so that build-time dependencies are taken from <varname>buildPackages</varname>, whereas run-time dependencies are taken from the top level attribute set.
|
||||||
For example, <varname>buildPackages.gcc</varname> should be used at build time, while <varname>gcc</varname> should be used at run time.
|
For example, <varname>buildPackages.gcc</varname> should be used at build time, while <varname>gcc</varname> should be used at run time.
|
||||||
Now, for most of Nixpkgs's history, there was no <varname>buildPackages</varname>, and most packages have not been refactored to use it explicitly.
|
Now, for most of Nixpkgs's history, there was no <varname>buildPackages</varname>, and most packages have not been refactored to use it explicitly.
|
||||||
Instead, one can use the four attributes used for specifying dependencies as documented in <link linkend="ssec-stdenv-attributes" />.
|
Instead, one can use the four attributes used for specifying dependencies as documented in <xref linkend="ssec-stdenv-attributes"/>.
|
||||||
We "splice" together the run-time and build-time package sets with <varname>callPackage</varname>, and then <varname>mkDerivation</varname> for each of four attributes pulls the right derivation out.
|
We "splice" together the run-time and build-time package sets with <varname>callPackage</varname>, and then <varname>mkDerivation</varname> for each of four attributes pulls the right derivation out.
|
||||||
This splicing can be skipped when not cross compiling as the package sets are the same, but is a bit slow for cross compiling.
|
This splicing can be skipped when not cross compiling as the package sets are the same, but is a bit slow for cross compiling.
|
||||||
Because of this, a best-of-both-worlds solution is in the works with no splicing or explicit access of <varname>buildPackages</varname> needed.
|
Because of this, a best-of-both-worlds solution is in the works with no splicing or explicit access of <varname>buildPackages</varname> needed.
|
||||||
For now, feel free to use either method.
|
For now, feel free to use either method.
|
||||||
</para>
|
</para>
|
||||||
|
<note><para>
|
||||||
|
There is also a "backlink" <varname>__targetPackages</varname>, yielding a package set whose <varname>buildPackages</varname> is the current package set.
|
||||||
|
This is a hack, though, to accommodate compilers with lousy build systems.
|
||||||
|
Please do not use this unless you are absolutely sure you are packaging such a compiler and there is no other way.
|
||||||
|
</para></note>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@@ -179,11 +200,27 @@
|
|||||||
More information needs to moved from the old wiki, especially <link xlink:href="https://nixos.org/wiki/CrossCompiling" />, for this section.
|
More information needs to moved from the old wiki, especially <link xlink:href="https://nixos.org/wiki/CrossCompiling" />, for this section.
|
||||||
</para></note>
|
</para></note>
|
||||||
<para>
|
<para>
|
||||||
Many sources (manual, wiki, etc) probably mention passing <varname>system</varname>, <varname>platform</varname>, and, optionally, <varname>crossSystem</varname> to nixpkgs:
|
Nixpkgs can be instantiated with <varname>localSystem</varname> alone, in which case there is no cross compiling and everything is built by and for that system,
|
||||||
<literal>import <nixpkgs> { system = ..; platform = ..; crossSystem = ..; }</literal>.
|
or also with <varname>crossSystem</varname>, in which case packages run on the latter, but all building happens on the former.
|
||||||
<varname>system</varname> and <varname>platform</varname> together determine the system on which packages are built, and <varname>crossSystem</varname> specifies the platform on which packages are ultimately intended to run, if it is different.
|
Both parameters take the same schema as the 3 (build, host, and target) platforms defined in the previous section.
|
||||||
This still works, but with more recent changes, one can alternatively pass <varname>localSystem</varname>, containing <varname>system</varname> and <varname>platform</varname>, for symmetry.
|
As mentioned above, <literal>lib.systems.examples</literal> has some platforms which are used as arguments for these parameters in practice.
|
||||||
|
You can use them programmatically, or on the command line like <command>nix-build <nixpkgs> --arg crossSystem '(import <nixpkgs/lib>).systems.examples.fooBarBaz'</command>.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
While one is free to pass both parameters in full, there's a lot of logic to fill in missing fields.
|
||||||
|
As discussed in the previous section, only one of <varname>system</varname>, <varname>config</varname>, and <varname>parsed</varname> is needed to infer the other two.
|
||||||
|
Additionally, <varname>libc</varname> will be inferred from <varname>parse</varname>.
|
||||||
|
Finally, <literal>localSystem.system</literal> is also <emphasis>impurely</emphasis> inferred based on the platform evaluation occurs.
|
||||||
|
This means it is often not necessary to pass <varname>localSystem</varname> at all, as in the command-line example in the previous paragraph.
|
||||||
|
</para>
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
Many sources (manual, wiki, etc) probably mention passing <varname>system</varname>, <varname>platform</varname>, along with the optional <varname>crossSystem</varname> to nixpkgs:
|
||||||
|
<literal>import <nixpkgs> { system = ..; platform = ..; crossSystem = ..; }</literal>.
|
||||||
|
Passing those two instead of <varname>localSystem</varname> is still supported for compatibility, but is discouraged.
|
||||||
|
Indeed, much of the inference we do for these parameters is motivated by compatibility as much as convenience.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
<para>
|
<para>
|
||||||
One would think that <varname>localSystem</varname> and <varname>crossSystem</varname> overlap horribly with the three <varname>*Platforms</varname> (<varname>buildPlatform</varname>, <varname>hostPlatform,</varname> and <varname>targetPlatform</varname>; see <varname>stage.nix</varname> or the manual).
|
One would think that <varname>localSystem</varname> and <varname>crossSystem</varname> overlap horribly with the three <varname>*Platforms</varname> (<varname>buildPlatform</varname>, <varname>hostPlatform,</varname> and <varname>targetPlatform</varname>; see <varname>stage.nix</varname> or the manual).
|
||||||
Actually, those identifiers are purposefully not used here to draw a subtle but important distinction:
|
Actually, those identifiers are purposefully not used here to draw a subtle but important distinction:
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ pkgs.stdenv.mkDerivation {
|
|||||||
extraHeader = ''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" '';
|
extraHeader = ''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" '';
|
||||||
in ''
|
in ''
|
||||||
{
|
{
|
||||||
pandoc '${inputFile}' -w docbook ${lib.optionalString useChapters "--chapters"} \
|
pandoc '${inputFile}' -w docbook ${lib.optionalString useChapters "--top-level-division=chapter"} \
|
||||||
--smart \
|
--smart \
|
||||||
| sed -e 's|<ulink url=|<link xlink:href=|' \
|
| sed -e 's|<ulink url=|<link xlink:href=|' \
|
||||||
-e 's|</ulink>|</link>|' \
|
-e 's|</ulink>|</link>|' \
|
||||||
|
|||||||
+5
-5
@@ -70,7 +70,7 @@
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
In the above example, the <varname>separateDebugInfo</varname> attribute is
|
In the above example, the <varname>separateDebugInfo</varname> attribute is
|
||||||
overriden to be true, thus building debug info for
|
overridden to be true, thus building debug info for
|
||||||
<varname>helloWithDebug</varname>, while all other attributes will be
|
<varname>helloWithDebug</varname>, while all other attributes will be
|
||||||
retained from the original <varname>hello</varname> package.
|
retained from the original <varname>hello</varname> package.
|
||||||
</para>
|
</para>
|
||||||
@@ -358,8 +358,8 @@
|
|||||||
<para>
|
<para>
|
||||||
<varname>pkgs.dockerTools</varname> is a set of functions for creating and
|
<varname>pkgs.dockerTools</varname> is a set of functions for creating and
|
||||||
manipulating Docker images according to the
|
manipulating Docker images according to the
|
||||||
<link xlink:href="https://github.com/docker/docker/blob/master/image/spec/v1.md#docker-image-specification-v100">
|
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#docker-image-specification-v120">
|
||||||
Docker Image Specification v1.0.0
|
Docker Image Specification v1.2.0
|
||||||
</link>. Docker itself is not used to perform any of the operations done by these
|
</link>. Docker itself is not used to perform any of the operations done by these
|
||||||
functions.
|
functions.
|
||||||
</para>
|
</para>
|
||||||
@@ -493,8 +493,8 @@
|
|||||||
<varname>config</varname> is used to specify the configuration of the
|
<varname>config</varname> is used to specify the configuration of the
|
||||||
containers that will be started off the built image in Docker.
|
containers that will be started off the built image in Docker.
|
||||||
The available options are listed in the
|
The available options are listed in the
|
||||||
<link xlink:href="https://github.com/docker/docker/blob/master/image/spec/v1.md#container-runconfig-field-descriptions">
|
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions">
|
||||||
Docker Image Specification v1.0.0
|
Docker Image Specification v1.2.0
|
||||||
</link>.
|
</link>.
|
||||||
</para>
|
</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|||||||
+1
-3
@@ -48,6 +48,4 @@ The binaries are made available via a [binary cache](https://cache.nixos.org).
|
|||||||
|
|
||||||
The current Nix expressions of the channels are available in the
|
The current Nix expressions of the channels are available in the
|
||||||
[`nixpkgs-channels`](https://github.com/NixOS/nixpkgs-channels) repository,
|
[`nixpkgs-channels`](https://github.com/NixOS/nixpkgs-channels) repository,
|
||||||
which has branches corresponding to the available channels. There is also the
|
which has branches corresponding to the available channels.
|
||||||
[Nixpkgs Monitor](http://monitor.nixos.org) which keeps track of updates
|
|
||||||
and security vulnerabilities.
|
|
||||||
|
|||||||
+231
-133
@@ -2,60 +2,120 @@
|
|||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
xml:id="sec-beam">
|
xml:id="sec-beam">
|
||||||
|
|
||||||
<title>Beam Languages (Erlang & Elixir)</title>
|
<title>BEAM Languages (Erlang, Elixir & LFE)</title>
|
||||||
<section xml:id="beam-introduction">
|
<section xml:id="beam-introduction">
|
||||||
<title>Introduction</title>
|
<title>Introduction</title>
|
||||||
<para>
|
<para>
|
||||||
In this document and related Nix expressions we use the term
|
In this document and related Nix expressions, we use the term,
|
||||||
<emphasis>Beam</emphasis> to describe the environment. Beam is
|
<emphasis>BEAM</emphasis>, to describe the environment. BEAM is the name
|
||||||
the name of the Erlang Virtial Machine and, as far as we know,
|
of the Erlang Virtual Machine and, as far as we're concerned, from a
|
||||||
from a packaging perspective all languages that run on Beam are
|
packaging perspective, all languages that run on the BEAM are
|
||||||
interchangable. The things that do change, like the build
|
interchangeable. That which varies, like the build system, is transparent
|
||||||
system, are transperant to the users of the package. So we make
|
to users of any given BEAM package, so we make no distinction.
|
||||||
no distinction.
|
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="build-tools">
|
<section xml:id="beam-structure">
|
||||||
|
<title>Structure</title>
|
||||||
|
<para>
|
||||||
|
All BEAM-related expressions are available via the top-level
|
||||||
|
<literal>beam</literal> attribute, which includes:
|
||||||
|
</para>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>interpreters</literal>: a set of compilers running on the
|
||||||
|
BEAM, including multiple Erlang/OTP versions
|
||||||
|
(<literal>beam.interpreters.erlangR19</literal>, etc), Elixir
|
||||||
|
(<literal>beam.interpreters.elixir</literal>) and LFE
|
||||||
|
(<literal>beam.interpreters.lfe</literal>).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>packages</literal>: a set of package sets, each compiled with
|
||||||
|
a specific Erlang/OTP version, e.g.
|
||||||
|
<literal>beam.packages.erlangR19</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
<para>
|
||||||
|
The default Erlang compiler, defined by
|
||||||
|
<literal>beam.interpreters.erlang</literal>, is aliased as
|
||||||
|
<literal>erlang</literal>. The default BEAM package set is defined by
|
||||||
|
<literal>beam.packages.erlang</literal> and aliased at the top level as
|
||||||
|
<literal>beamPackages</literal>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
To create a package set built with a custom Erlang version, use the
|
||||||
|
lambda, <literal>beam.packagesWith</literal>, which accepts an Erlang/OTP
|
||||||
|
derivation and produces a package set similar to
|
||||||
|
<literal>beam.packages.erlang</literal>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Many Erlang/OTP distributions available in
|
||||||
|
<literal>beam.interpreters</literal> have versions with ODBC and/or Java
|
||||||
|
enabled. For example, there's
|
||||||
|
<literal>beam.interpreters.erlangR19_odbc_javac</literal>, which
|
||||||
|
corresponds to <literal>beam.interpreters.erlangR19</literal>.
|
||||||
|
</para>
|
||||||
|
<para xml:id="erlang-call-package">
|
||||||
|
We also provide the lambda,
|
||||||
|
<literal>beam.packages.erlang.callPackage</literal>, which simplifies
|
||||||
|
writing BEAM package definitions by injecting all packages from
|
||||||
|
<literal>beam.packages.erlang</literal> into the top-level context.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
<section xml:id="build-tools">
|
||||||
<title>Build Tools</title>
|
<title>Build Tools</title>
|
||||||
<section xml:id="build-tools-rebar3">
|
<section xml:id="build-tools-rebar3">
|
||||||
<title>Rebar3</title>
|
<title>Rebar3</title>
|
||||||
<para>
|
<para>
|
||||||
By default Rebar3 wants to manage it's own dependencies. In the
|
By default, Rebar3 wants to manage its own dependencies. This is perfectly
|
||||||
normal non-Nix, this is perfectly acceptable. In the Nix world it
|
acceptable in the normal, non-Nix setup, but in the Nix world, it is not.
|
||||||
is not. To support this we have created two versions of rebar3,
|
To rectify this, we provide two versions of Rebar3:
|
||||||
<literal>rebar3</literal> and <literal>rebar3-open</literal>. The
|
<itemizedlist>
|
||||||
<literal>rebar3</literal> version has been patched to remove the
|
<listitem>
|
||||||
ability to download anything from it. If you are not running it a
|
<para>
|
||||||
nix-shell or a nix-build then its probably not going to work for
|
<literal>rebar3</literal>: patched to remove the ability to download
|
||||||
you. <literal>rebar3-open</literal> is the normal, un-modified
|
anything. When not running it via <literal>nix-shell</literal> or
|
||||||
rebar3. It should work exactly as would any other version of
|
<literal>nix-build</literal>, it's probably not going to work as
|
||||||
rebar3. Any Erlang package should rely on
|
desired.
|
||||||
<literal>rebar3</literal> and thats really what you should be
|
</para>
|
||||||
using too.
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>rebar3-open</literal>: the normal, unmodified Rebar3. It
|
||||||
|
should work exactly as would any other version of Rebar3. Any Erlang
|
||||||
|
package should rely on <literal>rebar3</literal> instead. See <xref
|
||||||
|
linkend="rebar3-packages"/>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="build-tools-other">
|
<section xml:id="build-tools-other">
|
||||||
<title>Mix & Erlang.mk</title>
|
<title>Mix & Erlang.mk</title>
|
||||||
<para>
|
<para>
|
||||||
Both Mix and Erlang.mk work exactly as you would expect. There
|
Both Mix and Erlang.mk work exactly as expected. There is a bootstrap
|
||||||
is a bootstrap process that needs to be run for both of
|
process that needs to be run for both, however, which is supported by the
|
||||||
them. However, that is supported by the
|
<literal>buildMix</literal> and <literal>buildErlangMk</literal>
|
||||||
<literal>buildMix</literal> and <literal>buildErlangMk</literal> derivations.
|
derivations, respectively.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="how-to-install-beam-packages">
|
<section xml:id="how-to-install-beam-packages">
|
||||||
<title>How to install Beam packages</title>
|
<title>How to Install BEAM Packages</title>
|
||||||
<para>
|
<para>
|
||||||
Beam packages are not registered in the top level simply because
|
BEAM packages are not registered at the top level, simply because they are
|
||||||
they are not relevant to the vast majority of Nix users. They are
|
not relevant to the vast majority of Nix users. They are installable using
|
||||||
installable using the <literal>beamPackages</literal> attribute
|
the <literal>beam.packages.erlang</literal> attribute set (aliased as
|
||||||
set.
|
<literal>beamPackages</literal>), which points to packages built by the
|
||||||
|
default Erlang/OTP version in Nixpkgs, as defined by
|
||||||
|
<literal>beam.interpreters.erlang</literal>.
|
||||||
|
|
||||||
You can list the avialable packages in the
|
To list the available packages in
|
||||||
<literal>beamPackages</literal> with the following command:
|
<literal>beamPackages</literal>, use the following command:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
@@ -69,115 +129,152 @@ beamPackages.meck meck-0.8.3
|
|||||||
beamPackages.rebar3-pc pc-1.1.0
|
beamPackages.rebar3-pc pc-1.1.0
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
To install any of those packages into your profile, refer to them by
|
To install any of those packages into your profile, refer to them by their
|
||||||
their attribute path (first column):
|
attribute path (first column):
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
$ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse
|
$ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
The attribute path of any Beam packages corresponds to the name
|
The attribute path of any BEAM package corresponds to the name of that
|
||||||
of that particular package in Hex or its OTP Application/Release name.
|
particular package in <link xlink:href="https://hex.pm">Hex</link> or its
|
||||||
|
OTP Application/Release name.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="packaging-beam-applications">
|
<section xml:id="packaging-beam-applications">
|
||||||
<title>Packaging Beam Applications</title>
|
<title>Packaging BEAM Applications</title>
|
||||||
<section xml:id="packaging-erlang-applications">
|
<section xml:id="packaging-erlang-applications">
|
||||||
<title>Erlang Applications</title>
|
<title>Erlang Applications</title>
|
||||||
<section xml:id="rebar3-packages">
|
<section xml:id="rebar3-packages">
|
||||||
<title>Rebar3 Packages</title>
|
<title>Rebar3 Packages</title>
|
||||||
<para>
|
<para>
|
||||||
There is a Nix functional called
|
The Nix function, <literal>buildRebar3</literal>, defined in
|
||||||
<literal>buildRebar3</literal>. We use this function to make a
|
<literal>beam.packages.erlang.buildRebar3</literal> and aliased at the
|
||||||
derivation that understands how to build the rebar3 project. For
|
top level, can be used to build a derivation that understands how to
|
||||||
example, the epression we use to build the <link
|
build a Rebar3 project. For example, we can build <link
|
||||||
xlink:href="https://github.com/erlang-nix/hex2nix">hex2nix</link>
|
xlink:href="https://github.com/erlang-nix/hex2nix">hex2nix</link> as
|
||||||
project follows.
|
follows:
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{stdenv, fetchFromGitHub, buildRebar3, ibrowse, jsx, erlware_commons }:
|
{ stdenv, fetchFromGitHub, buildRebar3, ibrowse, jsx, erlware_commons }:
|
||||||
|
|
||||||
buildRebar3 rec {
|
buildRebar3 rec {
|
||||||
name = "hex2nix";
|
name = "hex2nix";
|
||||||
version = "0.0.1";
|
version = "0.0.1";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "ericbmerritt";
|
owner = "ericbmerritt";
|
||||||
repo = "hex2nix";
|
repo = "hex2nix";
|
||||||
rev = "${version}";
|
rev = "${version}";
|
||||||
sha256 = "1w7xjidz1l5yjmhlplfx7kphmnpvqm67w99hd2m7kdixwdxq0zqg";
|
sha256 = "1w7xjidz1l5yjmhlplfx7kphmnpvqm67w99hd2m7kdixwdxq0zqg";
|
||||||
};
|
};
|
||||||
|
|
||||||
beamDeps = [ ibrowse jsx erlware_commons ];
|
beamDeps = [ ibrowse jsx erlware_commons ];
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
The only visible difference between this derivation and
|
Such derivations are callable with
|
||||||
something like <literal>stdenv.mkDerivation</literal> is that we
|
<literal>beam.packages.erlang.callPackage</literal> (see <xref
|
||||||
have added <literal>erlangDeps</literal> to the derivation. If
|
linkend="erlang-call-package"/>). To call this package using the normal
|
||||||
you add your Beam dependencies here they will be correctly
|
<literal>callPackage</literal>, refer to dependency packages via
|
||||||
handled by the system.
|
<literal>beamPackages</literal>, e.g.
|
||||||
|
<literal>beamPackages.ibrowse</literal>.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
If your package needs to compile native code via Rebar's port
|
Notably, <literal>buildRebar3</literal> includes
|
||||||
compilation mechenism. You should add <literal>compilePort =
|
<literal>beamDeps</literal>, while
|
||||||
true;</literal> to the derivation.
|
<literal>stdenv.mkDerivation</literal> does not. BEAM dependencies added
|
||||||
|
there will be correctly handled by the system.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If a package needs to compile native code via Rebar3's port compilation
|
||||||
|
mechanism, add <literal>compilePort = true;</literal> to the derivation.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="erlang-mk-packages">
|
<section xml:id="erlang-mk-packages">
|
||||||
<title>Erlang.mk Packages</title>
|
<title>Erlang.mk Packages</title>
|
||||||
<para>
|
<para>
|
||||||
Erlang.mk functions almost identically to Rebar. The only real
|
Erlang.mk functions similarly to Rebar3, except we use
|
||||||
difference is that <literal>buildErlangMk</literal> is called
|
<literal>buildErlangMk</literal> instead of
|
||||||
instead of <literal>buildRebar3</literal>
|
<literal>buildRebar3</literal>.
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{ buildErlangMk, fetchHex, cowlib, ranch }:
|
{ buildErlangMk, fetchHex, cowlib, ranch }:
|
||||||
buildErlangMk {
|
|
||||||
name = "cowboy";
|
|
||||||
version = "1.0.4";
|
|
||||||
src = fetchHex {
|
|
||||||
pkg = "cowboy";
|
|
||||||
version = "1.0.4";
|
|
||||||
sha256 =
|
|
||||||
"6a0edee96885fae3a8dd0ac1f333538a42e807db638a9453064ccfdaa6b9fdac";
|
|
||||||
};
|
|
||||||
beamDeps = [ cowlib ranch ];
|
|
||||||
|
|
||||||
meta = {
|
buildErlangMk {
|
||||||
description = ''Small, fast, modular HTTP server written in
|
name = "cowboy";
|
||||||
Erlang.'';
|
version = "1.0.4";
|
||||||
license = stdenv.lib.licenses.isc;
|
|
||||||
homepage = "https://github.com/ninenines/cowboy";
|
src = fetchHex {
|
||||||
};
|
pkg = "cowboy";
|
||||||
|
version = "1.0.4";
|
||||||
|
sha256 = "6a0edee96885fae3a8dd0ac1f333538a42e807db638a9453064ccfdaa6b9fdac";
|
||||||
|
};
|
||||||
|
|
||||||
|
beamDeps = [ cowlib ranch ];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = ''
|
||||||
|
Small, fast, modular HTTP server written in Erlang
|
||||||
|
'';
|
||||||
|
license = stdenv.lib.licenses.isc;
|
||||||
|
homepage = https://github.com/ninenines/cowboy;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="mix-packages">
|
<section xml:id="mix-packages">
|
||||||
<title>Mix Packages</title>
|
<title>Mix Packages</title>
|
||||||
<para>
|
<para>
|
||||||
Mix functions almost identically to Rebar. The only real
|
Mix functions similarly to Rebar3, except we use
|
||||||
difference is that <literal>buildMix</literal> is called
|
<literal>buildMix</literal> instead of <literal>buildRebar3</literal>.
|
||||||
instead of <literal>buildRebar3</literal>
|
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{ buildMix, fetchHex, plug, absinthe }:
|
{ buildMix, fetchHex, plug, absinthe }:
|
||||||
|
|
||||||
buildMix {
|
buildMix {
|
||||||
name = "absinthe_plug";
|
name = "absinthe_plug";
|
||||||
version = "1.0.0";
|
version = "1.0.0";
|
||||||
|
|
||||||
src = fetchHex {
|
src = fetchHex {
|
||||||
pkg = "absinthe_plug";
|
pkg = "absinthe_plug";
|
||||||
version = "1.0.0";
|
version = "1.0.0";
|
||||||
sha256 =
|
sha256 = "08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33";
|
||||||
"08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33";
|
|
||||||
};
|
};
|
||||||
beamDeps = [ plug absinthe];
|
|
||||||
|
beamDeps = [ plug absinthe ];
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
description = ''A plug for Absinthe, an experimental GraphQL
|
description = ''
|
||||||
toolkit'';
|
A plug for Absinthe, an experimental GraphQL toolkit
|
||||||
|
'';
|
||||||
license = stdenv.lib.licenses.bsd3;
|
license = stdenv.lib.licenses.bsd3;
|
||||||
homepage = "https://github.com/CargoSense/absinthe_plug";
|
homepage = https://github.com/CargoSense/absinthe_plug;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
Alternatively, we can use <literal>buildHex</literal> as a shortcut:
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
{ buildHex, buildMix, plug, absinthe }:
|
||||||
|
|
||||||
|
buildHex {
|
||||||
|
name = "absinthe_plug";
|
||||||
|
version = "1.0.0";
|
||||||
|
|
||||||
|
sha256 = "08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33";
|
||||||
|
|
||||||
|
builder = buildMix;
|
||||||
|
|
||||||
|
beamDeps = [ plug absinthe ];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = ''
|
||||||
|
A plug for Absinthe, an experimental GraphQL toolkit
|
||||||
|
'';
|
||||||
|
license = stdenv.lib.licenses.bsd3;
|
||||||
|
homepage = https://github.com/CargoSense/absinthe_plug;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
@@ -185,18 +282,18 @@ $ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse
|
|||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="how-to-develop">
|
<section xml:id="how-to-develop">
|
||||||
<title>How to develop</title>
|
<title>How to Develop</title>
|
||||||
<section xml:id="accessing-an-environment">
|
<section xml:id="accessing-an-environment">
|
||||||
<title>Accessing an Environment</title>
|
<title>Accessing an Environment</title>
|
||||||
<para>
|
<para>
|
||||||
Often, all you want to do is be able to access a valid
|
Often, we simply want to access a valid environment that contains a
|
||||||
environment that contains a specific package and its
|
specific package and its dependencies. We can accomplish that with the
|
||||||
dependencies. we can do that with the <literal>env</literal>
|
<literal>env</literal> attribute of a derivation. For example, let's say
|
||||||
part of a derivation. For example, lets say we want to access an
|
we want to access an Erlang REPL with <literal>ibrowse</literal> loaded
|
||||||
erlang repl with ibrowse loaded up. We could do the following.
|
up. We could do the following:
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
~/w/nixpkgs ❯❯❯ nix-shell -A beamPackages.ibrowse.env --run "erl"
|
$ nix-shell -A beamPackages.ibrowse.env --run "erl"
|
||||||
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
|
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
|
||||||
|
|
||||||
Eshell V7.0 (abort with ^G)
|
Eshell V7.0 (abort with ^G)
|
||||||
@@ -237,20 +334,19 @@ $ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse
|
|||||||
2>
|
2>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
Notice the <literal>-A beamPackages.ibrowse.env</literal>.That
|
Notice the <literal>-A beamPackages.ibrowse.env</literal>. That is the key
|
||||||
is the key to this functionality.
|
to this functionality.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="creating-a-shell">
|
<section xml:id="creating-a-shell">
|
||||||
<title>Creating a Shell</title>
|
<title>Creating a Shell</title>
|
||||||
<para>
|
<para>
|
||||||
Getting access to an environment often isn't enough to do real
|
Getting access to an environment often isn't enough to do real
|
||||||
development. Many times we need to create a
|
development. Usually, we need to create a <literal>shell.nix</literal>
|
||||||
<literal>shell.nix</literal> file and do our development inside
|
file and do our development inside of the environment specified therein.
|
||||||
of the environment specified by that file. This file looks a lot
|
This file looks a lot like the packaging described above, except that
|
||||||
like the packaging described above. The main difference is that
|
<literal>src</literal> points to the project root and we call the package
|
||||||
<literal>src</literal> points to project root and we call the
|
directly.
|
||||||
package directly.
|
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{ pkgs ? import "<nixpkgs"> {} }:
|
{ pkgs ? import "<nixpkgs"> {} }:
|
||||||
@@ -264,18 +360,19 @@ let
|
|||||||
name = "hex2nix";
|
name = "hex2nix";
|
||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
src = ./.;
|
src = ./.;
|
||||||
erlangDeps = [ ibrowse jsx erlware_commons ];
|
beamDeps = [ ibrowse jsx erlware_commons ];
|
||||||
};
|
};
|
||||||
drv = beamPackages.callPackage f {};
|
drv = beamPackages.callPackage f {};
|
||||||
|
|
||||||
in
|
in
|
||||||
drv
|
|
||||||
|
drv
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<section xml:id="building-in-a-shell">
|
<section xml:id="building-in-a-shell">
|
||||||
<title>Building in a shell</title>
|
<title>Building in a Shell (for Mix Projects)</title>
|
||||||
<para>
|
<para>
|
||||||
We can leveral the support of the Derivation, regardless of
|
We can leverage the support of the derivation, irrespective of the build
|
||||||
which build Derivation is called by calling the commands themselv.s
|
derivation, by calling the commands themselves.
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -335,42 +432,43 @@ analyze: build plt
|
|||||||
|
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
If you add the <literal>shell.nix</literal> as described and
|
Using a <literal>shell.nix</literal> as described (see <xref
|
||||||
user rebar as follows things should simply work. Aside from the
|
linkend="creating-a-shell"/>) should just work. Aside from
|
||||||
<literal>test</literal>, <literal>plt</literal>, and
|
<literal>test</literal>, <literal>plt</literal>, and
|
||||||
<literal>analyze</literal> the talks work just fine for all of
|
<literal>analyze</literal>, the Make targets work just fine for all of the
|
||||||
the build Derivations.
|
build derivations.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="generating-packages-from-hex-with-hex2nix">
|
<section xml:id="generating-packages-from-hex-with-hex2nix">
|
||||||
<title>Generating Packages from Hex with Hex2Nix</title>
|
<title>Generating Packages from Hex with <literal>hex2nix</literal></title>
|
||||||
<para>
|
<para>
|
||||||
Updating the Hex packages requires the use of the
|
Updating the <link xlink:href="https://hex.pm">Hex</link> package set
|
||||||
<literal>hex2nix</literal> tool. Given the path to the Erlang
|
requires <link
|
||||||
modules (usually
|
xlink:href="https://github.com/erlang-nix/hex2nix">hex2nix</link>. Given the
|
||||||
<literal>pkgs/development/erlang-modules</literal>). It will
|
path to the Erlang modules (usually
|
||||||
happily dump a file called
|
<literal>pkgs/development/erlang-modules</literal>), it will dump a file
|
||||||
<literal>hex-packages.nix</literal>. That file will contain all
|
called <literal>hex-packages.nix</literal>, containing all the packages that
|
||||||
the packages that use a recognized build system in Hex. However,
|
use a recognized build system in <link
|
||||||
it can't know whether or not all those packages are buildable.
|
xlink:href="https://hex.pm">Hex</link>. It can't be determined, however,
|
||||||
|
whether every package is buildable.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
To make life easier for our users, it makes good sense to go
|
To make life easier for our users, try to build every <link
|
||||||
ahead and attempt to build all those packages and remove the
|
xlink:href="https://hex.pm">Hex</link> package and remove those that fail.
|
||||||
ones that don't build. To do that, simply run the command (in
|
To do that, simply run the following command in the root of your
|
||||||
the root of your <literal>nixpkgs</literal> repository). that follows.
|
<literal>nixpkgs</literal> repository:
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
$ nix-build -A beamPackages
|
$ nix-build -A beamPackages
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
<para>
|
||||||
That will build every package in
|
That will attempt to build every package in
|
||||||
<literal>beamPackages</literal>. Then you can go through and
|
<literal>beamPackages</literal>. Then manually remove those that fail.
|
||||||
manually remove the ones that fail. Hopefully, someone will
|
Hopefully, someone will improve <link
|
||||||
improve <literal>hex2nix</literal> in the future to automate
|
xlink:href="https://github.com/erlang-nix/hex2nix">hex2nix</link> in the
|
||||||
that.
|
future to automate the process.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ standard Go programs.
|
|||||||
deis = buildGoPackage rec {
|
deis = buildGoPackage rec {
|
||||||
name = "deis-${version}";
|
name = "deis-${version}";
|
||||||
version = "1.13.0";
|
version = "1.13.0";
|
||||||
|
|
||||||
goPackagePath = "github.com/deis/deis"; <co xml:id='ex-buildGoPackage-1' />
|
goPackagePath = "github.com/deis/deis"; <co xml:id='ex-buildGoPackage-1' />
|
||||||
subPackages = [ "client" ]; <co xml:id='ex-buildGoPackage-2' />
|
subPackages = [ "client" ]; <co xml:id='ex-buildGoPackage-2' />
|
||||||
|
|
||||||
@@ -130,6 +130,9 @@ the following arguments are of special significance to the function:
|
|||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>To extract dependency information from a Go package in automated way use <link xlink:href="https://github.com/kamilchm/go2nix">go2nix</link>.
|
||||||
|
It can produce complete derivation and <varname>goDeps</varname> file for Go programs.</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<varname>buildGoPackage</varname> produces <xref linkend='chap-multiple-output' xrefstyle="select: title" />
|
<varname>buildGoPackage</varname> produces <xref linkend='chap-multiple-output' xrefstyle="select: title" />
|
||||||
where <varname>bin</varname> includes program binaries. You can test build a Go binary as follows:
|
where <varname>bin</varname> includes program binaries. You can test build a Go binary as follows:
|
||||||
@@ -160,7 +163,4 @@ done
|
|||||||
</screen>
|
</screen>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>To extract dependency information from a Go package in automated way use <link xlink:href="https://github.com/kamilchm/go2nix">go2nix</link>.
|
|
||||||
It can produce complete derivation and <varname>goDeps</varname> file for Go programs.</para>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
+467
-390
File diff suppressed because it is too large
Load Diff
+270
-185
@@ -2,115 +2,204 @@
|
|||||||
|
|
||||||
## User Guide
|
## User Guide
|
||||||
|
|
||||||
Several versions of Python are available on Nix as well as a high amount of
|
|
||||||
packages. The default interpreter is CPython 2.7.
|
|
||||||
|
|
||||||
### Using Python
|
### Using Python
|
||||||
|
|
||||||
|
#### Overview
|
||||||
|
|
||||||
|
Several versions of the Python interpreter are available on Nix, as well as a
|
||||||
|
high amount of packages. The attribute `python` refers to the default
|
||||||
|
interpreter, which is currently CPython 2.7. It is also possible to refer to
|
||||||
|
specific versions, e.g. `python35` refers to CPython 3.5, and `pypy` refers to
|
||||||
|
the default PyPy interpreter.
|
||||||
|
|
||||||
|
Python is used a lot, and in different ways. This affects also how it is
|
||||||
|
packaged. In the case of Python on Nix, an important distinction is made between
|
||||||
|
whether the package is considered primarily an application, or whether it should
|
||||||
|
be used as a library, i.e., of primary interest are the modules in
|
||||||
|
`site-packages` that should be importable.
|
||||||
|
|
||||||
|
In the Nixpkgs tree Python applications can be found throughout, depending on
|
||||||
|
what they do, and are called from the main package set. Python libraries,
|
||||||
|
however, are in separate sets, with one set per interpreter version.
|
||||||
|
|
||||||
|
The interpreters have several common attributes. One of these attributes is
|
||||||
|
`pkgs`, which is a package set of Python libraries for this specific
|
||||||
|
interpreter. E.g., the `toolz` package corresponding to the default interpreter
|
||||||
|
is `python.pkgs.toolz`, and the CPython 3.5 version is `python35.pkgs.toolz`.
|
||||||
|
The main package set contains aliases to these package sets, e.g.
|
||||||
|
`pythonPackages` refers to `python.pkgs` and `python35Packages` to
|
||||||
|
`python35.pkgs`.
|
||||||
|
|
||||||
#### Installing Python and packages
|
#### Installing Python and packages
|
||||||
|
|
||||||
It is important to make a distinction between Python packages that are
|
The Nix and NixOS manuals explain how packages are generally installed. In the
|
||||||
used as libraries, and applications that are written in Python.
|
case of Python and Nix, it is important to make a distinction between whether the
|
||||||
|
package is considered an application or a library.
|
||||||
|
|
||||||
Applications on Nix are installed typically into your user
|
Applications on Nix are typically installed into your user
|
||||||
profile imperatively using `nix-env -i`, and on NixOS declaratively by adding the
|
profile imperatively using `nix-env -i`, and on NixOS declaratively by adding the
|
||||||
package name to `environment.systemPackages` in `/etc/nixos/configuration.nix`.
|
package name to `environment.systemPackages` in `/etc/nixos/configuration.nix`.
|
||||||
Dependencies such as libraries are automatically installed and should not be
|
Dependencies such as libraries are automatically installed and should not be
|
||||||
installed explicitly.
|
installed explicitly.
|
||||||
|
|
||||||
The same goes for Python applications and libraries. Python applications can be
|
The same goes for Python applications and libraries. Python applications can be
|
||||||
installed in your profile, but Python libraries you would like to use to develop
|
installed in your profile. But Python libraries you would like to use for
|
||||||
cannot. If you do install libraries in your profile, then you will end up with
|
development cannot be installed, at least not individually, because they won't
|
||||||
import errors.
|
be able to find each other resulting in import errors. Instead, it is possible
|
||||||
|
to create an environment with `python.buildEnv` or `python.withPackages` where
|
||||||
|
the interpreter and other executables are able to find each other and all of the
|
||||||
|
modules.
|
||||||
|
|
||||||
#### Python environments using `nix-shell`
|
In the following examples we create an environment with Python 3.5, `numpy` and
|
||||||
|
`toolz`. As you may imagine, there is one limitation here, and that's that
|
||||||
|
you can install only one environment at a time. You will notice the complaints
|
||||||
|
about collisions when you try to install a second environment.
|
||||||
|
|
||||||
The recommended method for creating Python environments for development is with
|
##### Environment defined in separate `.nix` file
|
||||||
`nix-shell`. Executing
|
|
||||||
|
|
||||||
```sh
|
Create a file, e.g. `build.nix`, with the following expression
|
||||||
$ nix-shell -p python35Packages.numpy python35Packages.toolz
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
|
python35.withPackages (ps: with ps; [ numpy toolz ])
|
||||||
|
```
|
||||||
|
and install it in your profile with
|
||||||
|
```shell
|
||||||
|
nix-env -if build.nix
|
||||||
|
```
|
||||||
|
Now you can use the Python interpreter, as well as the extra packages (`numpy`,
|
||||||
|
`toolz`) that you added to the environment.
|
||||||
|
|
||||||
|
##### Environment defined in `~/.config/nixpkgs/config.nix`
|
||||||
|
|
||||||
|
If you prefer to, you could also add the environment as a package override to the Nixpkgs set, e.g.
|
||||||
|
using `config.nix`,
|
||||||
|
```nix
|
||||||
|
{ # ...
|
||||||
|
|
||||||
|
packageOverrides = pkgs: with pkgs; {
|
||||||
|
myEnv = python35.withPackages (ps: with ps; [ numpy toolz ]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
and install it in your profile with
|
||||||
|
```shell
|
||||||
|
nix-env -iA nixpkgs.myEnv
|
||||||
|
```
|
||||||
|
The environment is is installed by referring to the attribute, and considering
|
||||||
|
the `nixpkgs` channel was used.
|
||||||
|
|
||||||
|
##### Environment defined in `/etc/nixos/configuration.nix`
|
||||||
|
|
||||||
|
For the sake of completeness, here's another example how to install the environment system-wide.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ # ...
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
(python35.withPackages(ps: with ps; [ numpy toolz ]))
|
||||||
|
];
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
opens a Nix shell which has available the requested packages and dependencies.
|
#### Temporary Python environment with `nix-shell`
|
||||||
Now you can launch the Python interpreter (which is itself a dependency)
|
|
||||||
|
|
||||||
|
The examples in the previous section showed how to install a Python environment
|
||||||
|
into a profile. For development you may need to use multiple environments.
|
||||||
|
`nix-shell` gives the possibility to temporarily load another environment, akin
|
||||||
|
to `virtualenv`.
|
||||||
|
|
||||||
|
There are two methods for loading a shell with Python packages. The first and recommended method
|
||||||
|
is to create an environment with `python.buildEnv` or `python.withPackages` and load that. E.g.
|
||||||
|
```sh
|
||||||
|
$ nix-shell -p 'python35.withPackages(ps: with ps; [ numpy toolz ])'
|
||||||
|
```
|
||||||
|
opens a shell from which you can launch the interpreter
|
||||||
```sh
|
```sh
|
||||||
[nix-shell:~] python3
|
[nix-shell:~] python3
|
||||||
```
|
```
|
||||||
|
The other method, which is not recommended, does not create an environment and requires you to list the packages directly,
|
||||||
|
|
||||||
If the packages were not available yet in the Nix store, Nix would download or
|
```sh
|
||||||
build them automatically. A convenient option with `nix-shell` is the `--run`
|
$ nix-shell -p python35.pkgs.numpy python35.pkgs.toolz
|
||||||
option, with which you can execute a command in the `nix-shell`. Let's say we
|
```
|
||||||
want the above environment and directly run the Python interpreter
|
Again, it is possible to launch the interpreter from the shell.
|
||||||
|
The Python interpreter has the attribute `pkgs` which contains all Python libraries for that specific interpreter.
|
||||||
|
|
||||||
|
##### Load environment from `.nix` expression
|
||||||
|
As explained in the Nix manual, `nix-shell` can also load an
|
||||||
|
expression from a `.nix` file. Say we want to have Python 3.5, `numpy`
|
||||||
|
and `toolz`, like before, in an environment. Consider a `shell.nix` file
|
||||||
|
with
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
|
python35.withPackages (ps: [ps.numpy ps.toolz])
|
||||||
|
```
|
||||||
|
Executing `nix-shell` gives you again a Nix shell from which you can run Python.
|
||||||
|
|
||||||
|
What's happening here?
|
||||||
|
|
||||||
|
1. We begin with importing the Nix Packages collections. `import <nixpkgs>` imports the `<nixpkgs>` function, `{}` calls it and the `with` statement brings all attributes of `nixpkgs` in the local scope. These attributes form the main package set.
|
||||||
|
2. Then we create a Python 3.5 environment with the `withPackages` function.
|
||||||
|
3. The `withPackages` function expects us to provide a function as an argument that takes the set of all python packages and returns a list of packages to include in the environment. Here, we select the packages `numpy` and `toolz` from the package set.
|
||||||
|
|
||||||
|
##### Execute command with `--run`
|
||||||
|
A convenient option with `nix-shell` is the `--run`
|
||||||
|
option, with which you can execute a command in the `nix-shell`. We can
|
||||||
|
e.g. directly open a Python shell
|
||||||
```sh
|
```sh
|
||||||
$ nix-shell -p python35Packages.numpy python35Packages.toolz --run "python3"
|
$ nix-shell -p python35Packages.numpy python35Packages.toolz --run "python3"
|
||||||
```
|
```
|
||||||
|
or run a script
|
||||||
This way you can use the `--run` option also to directly run a script
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ nix-shell -p python35Packages.numpy python35Packages.toolz --run "python3 myscript.py"
|
$ nix-shell -p python35Packages.numpy python35Packages.toolz --run "python3 myscript.py"
|
||||||
```
|
```
|
||||||
|
|
||||||
In fact, for this specific use case there is a more convenient method. You can
|
##### `nix-shell` as shebang
|
||||||
|
In fact, for the second use case, there is a more convenient method. You can
|
||||||
add a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) to your script
|
add a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) to your script
|
||||||
specifying which dependencies Nix shell needs. With the following shebang, you
|
specifying which dependencies `nix-shell` needs. With the following shebang, you
|
||||||
can use `nix-shell myscript.py` and it will make available all dependencies and
|
can just execute `./myscript.py`, and it will make available all dependencies and
|
||||||
run the script in the `python3` shell.
|
run the script in the `python3` shell.
|
||||||
|
|
||||||
```py
|
```py
|
||||||
#! /usr/bin/env nix-shell
|
#! /usr/bin/env nix-shell
|
||||||
#! nix-shell -i python3 -p python3Packages.numpy
|
#! nix-shell -i 'python3.withPackages(ps: [ps.numpy])'
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
print(numpy.__version__)
|
print(numpy.__version__)
|
||||||
```
|
```
|
||||||
|
|
||||||
Likely you do not want to type your dependencies each and every time. What you
|
|
||||||
can do is write a simple Nix expression which sets up an environment for you,
|
|
||||||
requiring you only to type `nix-shell`. Say we want to have Python 3.5, `numpy`
|
|
||||||
and `toolz`, like before, in an environment. With a `shell.nix` file
|
|
||||||
containing
|
|
||||||
```nix
|
|
||||||
with import <nixpkgs> {};
|
|
||||||
|
|
||||||
(pkgs.python35.withPackages (ps: [ps.numpy ps.toolz])).env
|
|
||||||
```
|
|
||||||
executing `nix-shell` gives you again a Nix shell from which you can run Python.
|
|
||||||
|
|
||||||
What's happening here?
|
|
||||||
|
|
||||||
1. We begin with importing the Nix Packages collections. `import <nixpkgs>` import the `<nixpkgs>` function, `{}` calls it and the `with` statement brings all attributes of `nixpkgs` in the local scope. Therefore we can now use `pkgs`.
|
|
||||||
2. Then we create a Python 3.5 environment with the `withPackages` function.
|
|
||||||
3. The `withPackages` function expects us to provide a function as an argument that takes the set of all python packages and returns a list of packages to include in the environment. Here, we select the packages `numpy` and `toolz` from the package set.
|
|
||||||
4. And finally, for in interactive use we return the environment by using the `env` attribute.
|
|
||||||
|
|
||||||
### Developing with Python
|
### Developing with Python
|
||||||
|
|
||||||
|
Now that you know how to get a working Python environment with Nix, it is time
|
||||||
|
to go forward and start actually developing with Python. We will first have a
|
||||||
|
look at how Python packages are packaged on Nix. Then, we will look at how you
|
||||||
|
can use development mode with your code.
|
||||||
|
|
||||||
Now that you know how to get a working Python environment on Nix, it is time to go forward and start actually developing with Python.
|
#### Packaging a library
|
||||||
We will first have a look at how Python packages are packaged on Nix. Then, we will look how you can use development mode with your code.
|
|
||||||
|
|
||||||
#### Python packaging on Nix
|
With Nix all packages are built by functions. The main function in Nix for
|
||||||
|
building Python libraries is `buildPythonPackage`. Let's see how we can build the
|
||||||
On Nix all packages are built by functions. The main function in Nix for building Python packages is [`buildPythonPackage`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/interpreters/python/build-python-package.nix).
|
`toolz` package.
|
||||||
Let's see how we would build the `toolz` package. According to [`python-packages.nix`](https://raw.githubusercontent.com/NixOS/nixpkgs/master/pkgs/top-level/python-packages.nix) `toolz` is build using
|
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{ # ...
|
{ # ...
|
||||||
|
|
||||||
toolz = buildPythonPackage rec {
|
toolz = buildPythonPackage rec {
|
||||||
name = "toolz-${version}";
|
pname = "toolz";
|
||||||
version = "0.7.4";
|
version = "0.7.4";
|
||||||
|
name = "${pname}-${version}";
|
||||||
|
|
||||||
src = pkgs.fetchurl {
|
src = fetchPypi {
|
||||||
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
inherit pname version;
|
||||||
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
|
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
homepage = "http://github.com/pytoolz/toolz/";
|
homepage = "http://github.com/pytoolz/toolz/";
|
||||||
description = "List processing tools and functional utilities";
|
description = "List processing tools and functional utilities";
|
||||||
@@ -122,63 +211,37 @@ Let's see how we would build the `toolz` package. According to [`python-packages
|
|||||||
```
|
```
|
||||||
|
|
||||||
What happens here? The function `buildPythonPackage` is called and as argument
|
What happens here? The function `buildPythonPackage` is called and as argument
|
||||||
it accepts a set. In this case the set is a recursive set ([`rec`](http://nixos.org/nix/manual/#sec-constructs)).
|
it accepts a set. In this case the set is a recursive set, `rec`. One of the
|
||||||
One of the arguments is the name of the package, which consists of a basename
|
arguments is the name of the package, which consists of a basename (generally
|
||||||
(generally following the name on PyPi) and a version. Another argument, `src`
|
following the name on PyPi) and a version. Another argument, `src` specifies the
|
||||||
specifies the source, which in this case is fetched from an url. `fetchurl` not
|
source, which in this case is fetched from PyPI using the helper function
|
||||||
only downloads the target file, but also validates its hash. Furthermore, we
|
`fetchPypi`. The argument `doCheck` is used to set whether tests should be run
|
||||||
specify some (optional) [meta information](http://nixos.org/nixpkgs/manual/#chap-meta).
|
when building the package. Furthermore, we specify some (optional) meta
|
||||||
|
information. The output of the function is a derivation.
|
||||||
The output of the function is a derivation, which is an attribute with the name
|
|
||||||
`toolz` of the set `pythonPackages`. Actually, sets are created for all interpreter versions,
|
|
||||||
so e.g. `python27Packages`, `python35Packages` and `pypyPackages`.
|
|
||||||
|
|
||||||
|
An expression for `toolz` can be found in the Nixpkgs repository. As explained
|
||||||
|
in the introduction of this Python section, a derivation of `toolz` is available
|
||||||
|
for each interpreter version, e.g. `python35.pkgs.toolz` refers to the `toolz`
|
||||||
|
derivation corresponding to the CPython 3.5 interpreter.
|
||||||
The above example works when you're directly working on
|
The above example works when you're directly working on
|
||||||
`pkgs/top-level/python-packages.nix` in the Nixpkgs repository. Often though,
|
`pkgs/top-level/python-packages.nix` in the Nixpkgs repository. Often though,
|
||||||
you will want to test a Nix expression outside of the Nixpkgs tree. If you
|
you will want to test a Nix expression outside of the Nixpkgs tree.
|
||||||
create a `shell.nix` file with the following contents
|
|
||||||
|
|
||||||
```nix
|
The following expression creates a derivation for the `toolz` package,
|
||||||
with import <nixpkgs> {};
|
and adds it along with a `numpy` package to a Python environment.
|
||||||
|
|
||||||
pkgs.python35Packages.buildPythonPackage rec {
|
|
||||||
name = "toolz-${version}";
|
|
||||||
version = "0.8.0";
|
|
||||||
|
|
||||||
src = pkgs.fetchurl {
|
|
||||||
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
|
||||||
sha256 = "e8451af61face57b7c5d09e71c0d27b8005f001ead56e9fdf470417e5cc6d479";
|
|
||||||
};
|
|
||||||
|
|
||||||
doCheck = false;
|
|
||||||
|
|
||||||
meta = {
|
|
||||||
homepage = "http://github.com/pytoolz/toolz/";
|
|
||||||
description = "List processing tools and functional utilities";
|
|
||||||
license = licenses.bsd3;
|
|
||||||
maintainers = with maintainers; [ fridh ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
and then execute `nix-shell` will result in an environment in which you can use
|
|
||||||
Python 3.5 and the `toolz` package. As you can see we had to explicitly mention
|
|
||||||
for which Python version we want to build a package.
|
|
||||||
|
|
||||||
The above example considered only a single package. Generally you will want to use multiple packages.
|
|
||||||
If we create a `shell.nix` file with the following contents
|
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
with import <nixpkgs> {};
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
( let
|
( let
|
||||||
toolz = pkgs.python35Packages.buildPythonPackage rec {
|
my_toolz = python35.pkgs.buildPythonPackage rec {
|
||||||
name = "toolz-${version}";
|
pname = "toolz";
|
||||||
version = "0.8.0";
|
version = "0.7.4";
|
||||||
|
name = "${pname}-${version}";
|
||||||
|
|
||||||
src = pkgs.fetchurl {
|
src = python35.pkgs.fetchPypi {
|
||||||
url = "mirror://pypi/t/toolz/toolz-${version}.tar.gz";
|
inherit pname version;
|
||||||
sha256 = "e8451af61face57b7c5d09e71c0d27b8005f001ead56e9fdf470417e5cc6d479";
|
sha256 = "43c2c9e5e7a16b6c88ba3088a9bfc82f7db8e13378be7c78d6c14a5f8ed05afd";
|
||||||
};
|
};
|
||||||
|
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
@@ -189,24 +252,24 @@ with import <nixpkgs> {};
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
in pkgs.python35.withPackages (ps: [ps.numpy toolz])
|
in python35.withPackages (ps: [ps.numpy my_toolz])
|
||||||
).env
|
).env
|
||||||
```
|
```
|
||||||
|
Executing `nix-shell` will result in an environment in which you can use
|
||||||
|
Python 3.5 and the `toolz` package. As you can see we had to explicitly mention
|
||||||
|
for which Python version we want to build a package.
|
||||||
|
|
||||||
and again execute `nix-shell`, then we get a Python 3.5 environment with our
|
So, what did we do here? Well, we took the Nix expression that we used earlier
|
||||||
locally defined package as well as `numpy` which is build according to the
|
to build a Python environment, and said that we wanted to include our own
|
||||||
definition in Nixpkgs. What did we do here? Well, we took the Nix expression
|
version of `toolz`, named `my_toolz`. To introduce our own package in the scope
|
||||||
that we used earlier to build a Python environment, and said that we wanted to
|
of `withPackages` we used a `let` expression. You can see that we used
|
||||||
include our own version of `toolz`. To introduce our own package in the scope of
|
`ps.numpy` to select numpy from the nixpkgs package set (`ps`). We did not take
|
||||||
`withPackages` we used a
|
`toolz` from the Nixpkgs package set this time, but instead took our own version
|
||||||
[`let`](http://nixos.org/nix/manual/#sec-constructs) expression.
|
that we introduced with the `let` expression.
|
||||||
You can see that we used `ps.numpy` to select numpy from the nixpkgs package set (`ps`).
|
|
||||||
But we do not take `toolz` from the nixpkgs package set this time.
|
|
||||||
Instead, `toolz` will resolve to our local definition that we introduced with `let`.
|
|
||||||
|
|
||||||
### Handling dependencies
|
#### Handling dependencies
|
||||||
|
|
||||||
Our example, `toolz`, doesn't have any dependencies on other Python
|
Our example, `toolz`, does not have any dependencies on other Python
|
||||||
packages or system libraries. According to the manual, `buildPythonPackage`
|
packages or system libraries. According to the manual, `buildPythonPackage`
|
||||||
uses the arguments `buildInputs` and `propagatedBuildInputs` to specify dependencies. If something is
|
uses the arguments `buildInputs` and `propagatedBuildInputs` to specify dependencies. If something is
|
||||||
exclusively a build-time dependency, then the dependency should be included as a
|
exclusively a build-time dependency, then the dependency should be included as a
|
||||||
@@ -340,7 +403,7 @@ other packages we like to have in the environment, all specified with `propagate
|
|||||||
Indeed, we can just add any package we like to have in our environment to `propagatedBuildInputs`.
|
Indeed, we can just add any package we like to have in our environment to `propagatedBuildInputs`.
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
with import <nixpkgs>;
|
with import <nixpkgs> {};
|
||||||
with pkgs.python35Packages;
|
with pkgs.python35Packages;
|
||||||
|
|
||||||
buildPythonPackage rec {
|
buildPythonPackage rec {
|
||||||
@@ -423,7 +486,7 @@ and in this case the `python35` interpreter is automatically used.
|
|||||||
### Interpreters
|
### Interpreters
|
||||||
|
|
||||||
Versions 2.7, 3.3, 3.4, 3.5 and 3.6 of the CPython interpreter are available as
|
Versions 2.7, 3.3, 3.4, 3.5 and 3.6 of the CPython interpreter are available as
|
||||||
respectively `python27`, `python33`, `python34`, `python35` and `python36`. The PyPy interpreter
|
respectively `python27`, `python34`, `python35` and `python36`. The PyPy interpreter
|
||||||
is available as `pypy`. The aliases `python2` and `python3` correspond to respectively `python27` and
|
is available as `pypy`. The aliases `python2` and `python3` correspond to respectively `python27` and
|
||||||
`python35`. The default interpreter, `python`, maps to `python2`.
|
`python35`. The default interpreter, `python`, maps to `python2`.
|
||||||
The Nix expressions for the interpreters can be found in
|
The Nix expressions for the interpreters can be found in
|
||||||
@@ -469,7 +532,6 @@ sets are
|
|||||||
|
|
||||||
* `pkgs.python26Packages`
|
* `pkgs.python26Packages`
|
||||||
* `pkgs.python27Packages`
|
* `pkgs.python27Packages`
|
||||||
* `pkgs.python33Packages`
|
|
||||||
* `pkgs.python34Packages`
|
* `pkgs.python34Packages`
|
||||||
* `pkgs.python35Packages`
|
* `pkgs.python35Packages`
|
||||||
* `pkgs.python36Packages`
|
* `pkgs.python36Packages`
|
||||||
@@ -528,7 +590,7 @@ By default tests are run because `doCheck = true`. Test dependencies, like
|
|||||||
e.g. the test runner, should be added to `buildInputs`.
|
e.g. the test runner, should be added to `buildInputs`.
|
||||||
|
|
||||||
By default `meta.platforms` is set to the same value
|
By default `meta.platforms` is set to the same value
|
||||||
as the interpreter unless overriden otherwise.
|
as the interpreter unless overridden otherwise.
|
||||||
|
|
||||||
##### `buildPythonPackage` parameters
|
##### `buildPythonPackage` parameters
|
||||||
|
|
||||||
@@ -546,6 +608,35 @@ All parameters from `mkDerivation` function are still supported.
|
|||||||
* `catchConflicts` If `true`, abort package build if a package name appears more than once in dependency tree. Default is `true`.
|
* `catchConflicts` If `true`, abort package build if a package name appears more than once in dependency tree. Default is `true`.
|
||||||
* `checkInputs` Dependencies needed for running the `checkPhase`. These are added to `buildInputs` when `doCheck = true`.
|
* `checkInputs` Dependencies needed for running the `checkPhase`. These are added to `buildInputs` when `doCheck = true`.
|
||||||
|
|
||||||
|
##### Overriding Python packages
|
||||||
|
|
||||||
|
The `buildPythonPackage` function has a `overridePythonAttrs` method that
|
||||||
|
can be used to override the package. In the following example we create an
|
||||||
|
environment where we have the `blaze` package using an older version of `pandas`.
|
||||||
|
We override first the Python interpreter and pass
|
||||||
|
`packageOverrides` which contains the overrides for packages in the package set.
|
||||||
|
|
||||||
|
```nix
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
|
(let
|
||||||
|
python = let
|
||||||
|
packageOverrides = self: super: {
|
||||||
|
pandas = super.pandas.overridePythonAttrs(old: rec {
|
||||||
|
version = "0.19.1";
|
||||||
|
name = "pandas-${version}";
|
||||||
|
src = super.fetchPypi {
|
||||||
|
pname = "pandas";
|
||||||
|
inherit version;
|
||||||
|
sha256 = "08blshqj9zj1wyjhhw3kl2vas75vhhicvv72flvf1z3jvapgw295";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
in pkgs.python3.override {inherit packageOverrides;};
|
||||||
|
|
||||||
|
in python.withPackages(ps: [ps.blaze])).env
|
||||||
|
```
|
||||||
|
|
||||||
#### `buildPythonApplication` function
|
#### `buildPythonApplication` function
|
||||||
|
|
||||||
The `buildPythonApplication` function is practically the same as `buildPythonPackage`.
|
The `buildPythonApplication` function is practically the same as `buildPythonPackage`.
|
||||||
@@ -580,7 +671,7 @@ running `nix-shell` with the following `shell.nix`
|
|||||||
with import <nixpkgs> {};
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
(python3.buildEnv.override {
|
(python3.buildEnv.override {
|
||||||
extraLibs = with python3Packages; [ numpy requests2 ];
|
extraLibs = with python3Packages; [ numpy requests ];
|
||||||
}).env
|
}).env
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -622,7 +713,7 @@ attribute. The `shell.nix` file from the previous section can thus be also writt
|
|||||||
```nix
|
```nix
|
||||||
with import <nixpkgs> {};
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
(python33.withPackages (ps: [ps.numpy ps.requests2])).env
|
(python36.withPackages (ps: [ps.numpy ps.requests])).env
|
||||||
```
|
```
|
||||||
|
|
||||||
In contrast to `python.buildEnv`, `python.withPackages` does not support the more advanced options
|
In contrast to `python.buildEnv`, `python.withPackages` does not support the more advanced options
|
||||||
@@ -683,65 +774,36 @@ The `buildPythonPackage` function sets `DETERMINISTIC_BUILD=1` and
|
|||||||
Both are also exported in `nix-shell`.
|
Both are also exported in `nix-shell`.
|
||||||
|
|
||||||
|
|
||||||
|
### Automatic tests
|
||||||
|
|
||||||
|
It is recommended to test packages as part of the build process.
|
||||||
|
Source distributions (`sdist`) often include test files, but not always.
|
||||||
|
|
||||||
|
By default the command `python setup.py test` is run as part of the
|
||||||
|
`checkPhase`, but often it is necessary to pass a custom `checkPhase`. An
|
||||||
|
example of such a situation is when `py.test` is used.
|
||||||
|
|
||||||
|
#### Common issues
|
||||||
|
|
||||||
|
- Non-working tests can often be deselected. By default `buildPythonPackage` runs `python setup.py test`.
|
||||||
|
Most python modules follows the standard test protocol where the pytest runner can be used instead.
|
||||||
|
`py.test` supports a `-k` parameter to ignore test methods or classes:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
buildPythonPackage {
|
||||||
|
# ...
|
||||||
|
# assumes the tests are located in tests
|
||||||
|
checkInputs = [ pytest ];
|
||||||
|
checkPhase = ''
|
||||||
|
py.test -k 'not function_name and not other_function' tests
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Unicode issues can typically be fixed by including `glibcLocales` in `buildInputs` and exporting `LC_ALL=en_US.utf-8`.
|
||||||
|
- Tests that attempt to access `$HOME` can be fixed by using the following work-around before running tests (e.g. `preCheck`): `export HOME=$(mktemp -d)`
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
### How can I install a working Python environment?
|
|
||||||
|
|
||||||
As explained in the user's guide installing individual Python packages
|
|
||||||
imperatively with `nix-env -i` or declaratively in `environment.systemPackages`
|
|
||||||
is not supported. However, it is possible to install a Python environment with packages (`python.buildEnv`).
|
|
||||||
|
|
||||||
In the following examples we create an environment with Python 3.5, `numpy` and `ipython`.
|
|
||||||
As you might imagine there is one limitation here, and that's you can install
|
|
||||||
only one environment at a time. You will notice the complaints about collisions
|
|
||||||
when you try to install a second environment.
|
|
||||||
|
|
||||||
#### Environment defined in separate `.nix` file
|
|
||||||
|
|
||||||
Create a file, e.g. `build.nix`, with the following expression
|
|
||||||
```nix
|
|
||||||
with import <nixpkgs> {};
|
|
||||||
|
|
||||||
pkgs.python35.withPackages (ps: with ps; [ numpy ipython ])
|
|
||||||
```
|
|
||||||
and install it in your profile with
|
|
||||||
```shell
|
|
||||||
nix-env -if build.nix
|
|
||||||
```
|
|
||||||
Now you can use the Python interpreter, as well as the extra packages that you added to the environment.
|
|
||||||
|
|
||||||
#### Environment defined in `~/.nixpkgs/config.nix`
|
|
||||||
|
|
||||||
If you prefer to, you could also add the environment as a package override to the Nixpkgs set.
|
|
||||||
```nix
|
|
||||||
{ # ...
|
|
||||||
|
|
||||||
packageOverrides = pkgs: with pkgs; {
|
|
||||||
myEnv = python35.withPackages (ps: with ps; [ numpy ipython ]);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
and install it in your profile with
|
|
||||||
```shell
|
|
||||||
nix-env -iA nixpkgs.myEnv
|
|
||||||
```
|
|
||||||
|
|
||||||
We're installing using the attribute path and assume the channels is named `nixpkgs`.
|
|
||||||
Note that I'm using the attribute path here.
|
|
||||||
|
|
||||||
#### Environment defined in `/etc/nixos/configuration.nix`
|
|
||||||
|
|
||||||
For the sake of completeness, here's another example how to install the environment system-wide.
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ # ...
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
(python35.withPackages(ps: with ps; [ numpy ipython ]))
|
|
||||||
];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### How to solve circular dependencies?
|
### How to solve circular dependencies?
|
||||||
|
|
||||||
Consider the packages `A` and `B` that depend on each other. When packaging `B`,
|
Consider the packages `A` and `B` that depend on each other. When packaging `B`,
|
||||||
@@ -755,17 +817,17 @@ In the following example we rename the `pandas` package and build it.
|
|||||||
```nix
|
```nix
|
||||||
with import <nixpkgs> {};
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
let
|
(let
|
||||||
python = let
|
python = let
|
||||||
packageOverrides = self: super: {
|
packageOverrides = self: super: {
|
||||||
pandas = super.pandas.override {name="foo";};
|
pandas = super.pandas.overridePythonAttrs(old: {name="foo";});
|
||||||
};
|
};
|
||||||
in pkgs.python35.override {inherit packageOverrides;};
|
in pkgs.python35.override {inherit packageOverrides;};
|
||||||
|
|
||||||
in python.pkgs.pandas
|
in python.withPackages(ps: [ps.pandas])).env
|
||||||
```
|
```
|
||||||
Using `nix-build` on this expression will build the package `pandas`
|
Using `nix-build` on this expression will build an environment that contains the
|
||||||
but with the new name `foo`.
|
package `pandas` but with the new name `foo`.
|
||||||
|
|
||||||
All packages in the package set will use the renamed package.
|
All packages in the package set will use the renamed package.
|
||||||
A typical use case is to switch to another version of a certain package.
|
A typical use case is to switch to another version of a certain package.
|
||||||
@@ -923,14 +985,37 @@ If you need to change a package's attribute(s) from `configuration.nix` you coul
|
|||||||
|
|
||||||
If you are using the `bepasty-server` package somewhere, for example in `systemPackages` or indirectly from `services.bepasty`, then a `nixos-rebuild switch` will rebuild the system but with the `bepasty-server` package using a different `src` attribute. This way one can modify `python` based software/libraries easily. Using `self` and `super` one can also alter dependencies (`buildInputs`) between the old state (`self`) and new state (`super`).
|
If you are using the `bepasty-server` package somewhere, for example in `systemPackages` or indirectly from `services.bepasty`, then a `nixos-rebuild switch` will rebuild the system but with the `bepasty-server` package using a different `src` attribute. This way one can modify `python` based software/libraries easily. Using `self` and `super` one can also alter dependencies (`buildInputs`) between the old state (`self`) and new state (`super`).
|
||||||
|
|
||||||
|
### How to override a Python package using overlays?
|
||||||
|
|
||||||
|
To alter a python package using overlays, you would use the following approach:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
self: super:
|
||||||
|
rec {
|
||||||
|
python = super.python.override {
|
||||||
|
packageOverrides = python-self: python-super: {
|
||||||
|
bepasty-server = python-super.bepasty-server.overrideAttrs ( oldAttrs: {
|
||||||
|
src = self.pkgs.fetchgit {
|
||||||
|
url = "https://github.com/bepasty/bepasty-server";
|
||||||
|
sha256 = "9ziqshmsf0rjvdhhca55sm0x8jz76fsf2q4rwh4m6lpcf8wr0nps";
|
||||||
|
rev = "e2516e8cf4f2afb5185337073607eb9e84a61d2d";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
pythonPackages = python.pkgs;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
### Contributing guidelines
|
### Contributing guidelines
|
||||||
|
|
||||||
Following rules are desired to be respected:
|
Following rules are desired to be respected:
|
||||||
|
|
||||||
* Python libraries are supposed to be called from `python-packages.nix` and packaged with `buildPythonPackage`. The expression of a library should be in `pkgs/development/python-modules/<name>/default.nix`. Libraries in `pkgs/top-level/python-packages.nix` are sorted quasi-alphabetically to avoid merge conflicts.
|
* Python libraries are called from `python-packages.nix` and packaged with `buildPythonPackage`. The expression of a library should be in `pkgs/development/python-modules/<name>/default.nix`. Libraries in `pkgs/top-level/python-packages.nix` are sorted quasi-alphabetically to avoid merge conflicts.
|
||||||
* Python applications live outside of `python-packages.nix` and are packaged with `buildPythonApplication`.
|
* Python applications live outside of `python-packages.nix` and are packaged with `buildPythonApplication`.
|
||||||
* Make sure libraries build for all Python interpreters.
|
* Make sure libraries build for all Python interpreters.
|
||||||
* By default we enable tests. Make sure the tests are found and, in the case of libraries, are passing for all interpreters. If certain tests fail they can be disabled individually. Try to avoid disabling the tests altogether. In any case, when you disable tests, leave a comment explaining why.
|
* By default we enable tests. Make sure the tests are found and, in the case of libraries, are passing for all interpreters. If certain tests fail they can be disabled individually. Try to avoid disabling the tests altogether. In any case, when you disable tests, leave a comment explaining why.
|
||||||
* Commit names of Python libraries should include `pythonPackages`, for example `pythonPackages.numpy: 1.11 -> 1.12`.
|
* Commit names of Python libraries should reflect that they are Python libraries, so write for example `pythonPackages.numpy: 1.11 -> 1.12`.
|
||||||
|
|
||||||
|
|||||||
@@ -2,31 +2,55 @@
|
|||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
xml:id="sec-language-qt">
|
xml:id="sec-language-qt">
|
||||||
|
|
||||||
<title>Qt and KDE</title>
|
<title>Qt</title>
|
||||||
|
|
||||||
<para>Qt is a comprehensive desktop and mobile application development toolkit for C++. Legacy support is available for Qt 3 and Qt 4, but all current development uses Qt 5. The Qt 5 packages in Nixpkgs are updated frequently to take advantage of new features, but older versions are typically retained to support packages that may not be compatible with the latest version. When packaging applications and libraries for Nixpkgs, it is important to ensure that compatible versions of Qt 5 are used throughout; this consideration motivates the tools described below.</para>
|
<para>
|
||||||
|
Qt is a comprehensive desktop and mobile application development toolkit for C++.
|
||||||
|
Legacy support is available for Qt 3 and Qt 4, but all current development uses Qt 5.
|
||||||
|
The Qt 5 packages in Nixpkgs are updated frequently to take advantage of new features,
|
||||||
|
but older versions are typically retained until their support window ends.
|
||||||
|
The most important consideration in packaging Qt-based software is ensuring that each package and all its dependencies use the same version of Qt 5;
|
||||||
|
this consideration motivates most of the tools described below.
|
||||||
|
</para>
|
||||||
|
|
||||||
<section xml:id="ssec-qt-libraries"><title>Libraries</title>
|
<section xml:id="ssec-qt-libraries"><title>Packaging Libraries for Nixpkgs</title>
|
||||||
|
|
||||||
<para>Libraries that depend on Qt 5 should be built with each available version to avoid linking a dependent package against incompatible versions of Qt 5. (Although Qt 5 maintains backward ABI compatibility, linking against multiple versions at once is generally not possible; at best it will lead to runtime faults.) Packages that provide libraries should be added to the top-level function <varname>mkLibsForQt5</varname>, which is used to build a set of libraries for every Qt 5 version. The <varname>callPackage</varname> provided in this scope will ensure that only one Qt version will be used throughout the dependency tree. Dependencies should be imported unqualified, i.e. <literal>qtbase</literal> not <literal>qt5.qtbase</literal>, so that <varname>callPackage</varname> can do its work. <emphasis>Do not</emphasis> import a package set such as <literal>qt5</literal> or <literal>libsForQt5</literal> into your package; although it may work fine in the moment, it could well break at the next Qt update.</para>
|
<para>
|
||||||
|
Whenever possible, libraries that use Qt 5 should be built with each available version.
|
||||||
|
Packages providing libraries should be added to the top-level function <varname>mkLibsForQt5</varname>,
|
||||||
|
which is used to build a set of libraries for every Qt 5 version.
|
||||||
|
A special <varname>callPackage</varname> function is used in this scope to ensure that the entire dependency tree uses the same Qt 5 version.
|
||||||
|
Import dependencies unqualified, i.e., <literal>qtbase</literal> not <literal>qt5.qtbase</literal>.
|
||||||
|
<emphasis>Do not</emphasis> import a package set such as <literal>qt5</literal> or <literal>libsForQt5</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>If a library does not support a particular version of Qt 5, it is best to mark it as broken by setting its <literal>meta.broken</literal> attribute. A package may be marked broken for certain versions by testing the <literal>qtbase.version</literal> attribute, which will always give the current Qt 5 version.</para>
|
<para>
|
||||||
|
If a library does not support a particular version of Qt 5, it is best to mark it as broken by setting its <literal>meta.broken</literal> attribute.
|
||||||
|
A package may be marked broken for certain versions by testing the <literal>qtbase.version</literal> attribute, which will always give the current Qt 5 version.
|
||||||
|
</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="ssec-qt-applications"><title>Applications</title>
|
<section xml:id="ssec-qt-applications"><title>Packaging Applications for Nixpkgs</title>
|
||||||
|
|
||||||
<para>Applications generally do not need to be built with every Qt version because they do not provide any libraries for dependent packages to link against. The primary consideration is merely ensuring that the application itself and its dependencies are linked against only one version of Qt. To call your application expression, use <literal>libsForQt5.callPackage</literal> instead of <literal>callPackage</literal>. Dependencies should be imported unqualified, i.e. <literal>qtbase</literal> not <literal>qt5.qtbase</literal>. <emphasis>Do not</emphasis> import a package set such as <literal>qt5</literal> or <literal>libsForQt5</literal> into your package; although it may work fine in the moment, it could well break at the next Qt update.</para>
|
<para>
|
||||||
|
Call your application expression using <literal>libsForQt5.callPackage</literal> instead of <literal>callPackage</literal>.
|
||||||
|
Import dependencies unqualified, i.e., <literal>qtbase</literal> not <literal>qt5.qtbase</literal>.
|
||||||
|
<emphasis>Do not</emphasis> import a package set such as <literal>qt5</literal> or <literal>libsForQt5</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>It is generally best to build an application package against the <varname>libsForQt5</varname> library set. In case a package does not build with the latest Qt version, it is possible to pick a set pinned to a particular version, e.g. <varname>libsForQt55</varname> for Qt 5.5, if that is the latest version the package supports.</para>
|
<para>
|
||||||
|
Qt 5 maintains strict backward compatibility, so it is generally best to build an application package against the latest version using the <varname>libsForQt5</varname> library set.
|
||||||
|
In case a package does not build with the latest Qt version, it is possible to pick a set pinned to a particular version, e.g. <varname>libsForQt55</varname> for Qt 5.5, if that is the latest version the package supports.
|
||||||
|
If a package must be pinned to an older Qt version, be sure to file a bug upstream;
|
||||||
|
because Qt is strictly backwards-compatible, any incompatibility is by definition a bug in the application.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>Qt-based applications require that several paths be set at runtime. This is accomplished by wrapping the provided executables in a package with <literal>wrapQtProgram</literal> or <literal>makeQtWrapper</literal> during the <literal>postFixup</literal> phase. To use the wrapper generators, add <literal>makeQtWrapper</literal> to <literal>nativeBuildInputs</literal>. The wrapper generators support the same options as <literal>wrapProgram</literal> and <literal>makeWrapper</literal> respectively. It is usually only necessary to generate wrappers for programs intended to be invoked by the user.</para>
|
<para>
|
||||||
|
When testing applications in Nixpkgs, it is a common practice to build the package with <literal>nix-build</literal> and run it using the created symbolic link.
|
||||||
</section>
|
This will not work with Qt applications, however, because they have many hard runtime requirements that can only be guaranteed if the package is actually installed.
|
||||||
|
To test a Qt application, install it with <literal>nix-env</literal> or run it inside <literal>nix-shell</literal>.
|
||||||
<section xml:id="ssec-qt-kde"><title>KDE</title>
|
</para>
|
||||||
|
|
||||||
<para>The KDE Frameworks are a set of libraries for Qt 5 which form the basis of the Plasma desktop environment and the KDE Applications suite. Packaging a Frameworks-based library does not require any steps beyond those described above for general Qt-based libraries. Frameworks-based applications should not use <literal>makeQtWrapper</literal>; instead, use <literal>kdeWrapper</literal> to create the necessary wrappers: <literal>kdeWrapper { unwrapped = <replaceable>expr</replaceable>; targets = <replaceable>exes</replaceable>; }</literal>, where <replaceable>expr</replaceable> is the un-wrapped package expression and <replaceable>exes</replaceable> is a list of strings giving the relative paths to programs in the package which should be wrapped.</para>
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,14 @@
|
|||||||
|
|
||||||
<title>Ruby</title>
|
<title>Ruby</title>
|
||||||
|
|
||||||
<para>There currently is support to bundle applications that are packaged as Ruby gems. The utility "bundix" allows you to write a <filename>Gemfile</filename>, let bundler create a <filename>Gemfile.lock</filename>, and then convert
|
<para>There currently is support to bundle applications that are packaged as
|
||||||
this into a nix expression that contains all Gem dependencies automatically.</para>
|
Ruby gems. The utility "bundix" allows you to write a
|
||||||
|
<filename>Gemfile</filename>, let bundler create a
|
||||||
|
<filename>Gemfile.lock</filename>, and then convert this into a nix
|
||||||
|
expression that contains all Gem dependencies automatically.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>For example, to package sensu, we did:</para>
|
<para>For example, to package sensu, we did:</para>
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
<![CDATA[$ cd pkgs/servers/monitoring
|
<![CDATA[$ cd pkgs/servers/monitoring
|
||||||
@@ -16,7 +20,7 @@ $ cd sensu
|
|||||||
$ cat > Gemfile
|
$ cat > Gemfile
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
gem 'sensu'
|
gem 'sensu'
|
||||||
$ $(nix-build '<nixpkgs>' -A bundix)/bin/bundix --magic
|
$ $(nix-build '<nixpkgs>' -A bundix --no-out-link)/bin/bundix --magic
|
||||||
$ cat > default.nix
|
$ cat > default.nix
|
||||||
{ lib, bundlerEnv, ruby }:
|
{ lib, bundlerEnv, ruby }:
|
||||||
|
|
||||||
@@ -38,15 +42,61 @@ bundlerEnv rec {
|
|||||||
}]]>
|
}]]>
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
<para>Please check in the <filename>Gemfile</filename>, <filename>Gemfile.lock</filename> and the <filename>gemset.nix</filename> so future updates can be run easily.
|
<para>Please check in the <filename>Gemfile</filename>,
|
||||||
|
<filename>Gemfile.lock</filename> and the
|
||||||
|
<filename>gemset.nix</filename> so future updates can be run easily.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>Resulting derivations also have two helpful items, <literal>env</literal> and <literal>wrapper</literal>. The first one allows one to quickly drop into
|
<para>For tools written in Ruby - i.e. where the desire is to install
|
||||||
<command>nix-shell</command> with the specified environment present. E.g. <command>nix-shell -A sensu.env</command> would give you an environment with Ruby preset
|
a package and then execute e.g. <command>rake</command> at the command
|
||||||
so it has all the libraries necessary for <literal>sensu</literal> in its paths. The second one can be used to make derivations from custom Ruby scripts which have
|
line, there is an alternative builder called <literal>bundlerApp</literal>.
|
||||||
<filename>Gemfile</filename>s with their dependencies specified. It is a derivation with <command>ruby</command> wrapped so it can find all the needed dependencies.
|
Set up the <filename>gemset.nix</filename> the same way, and then, for
|
||||||
For example, to make a derivation <literal>my-script</literal> for a <filename>my-script.rb</filename> (which should be placed in <filename>bin</filename>) you should
|
example:
|
||||||
run <command>bundix</command> as specified above and then use <literal>bundlerEnv</literal> lile this:</para>
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
<![CDATA[{ lib, bundlerApp }:
|
||||||
|
|
||||||
|
bundlerApp {
|
||||||
|
pname = "corundum";
|
||||||
|
gemdir = ./.;
|
||||||
|
exes = [ "corundum-skel" ];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Tool and libraries for maintaining Ruby gems.";
|
||||||
|
homepage = https://github.com/nyarly/corundum;
|
||||||
|
license = licenses.mit;
|
||||||
|
maintainers = [ maintainers.nyarly ];
|
||||||
|
platforms = platforms.unix;
|
||||||
|
};
|
||||||
|
}]]>
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>The chief advantage of <literal>bundlerApp</literal> over
|
||||||
|
<literal>bundlerEnv</literal> is the executables introduced in the
|
||||||
|
environment are precisely those selected in the <literal>exes</literal>
|
||||||
|
list, as opposed to <literal>bundlerEnv</literal> which adds all the
|
||||||
|
executables made available by gems in the gemset, which can mean e.g.
|
||||||
|
<command>rspec</command> or <command>rake</command> in unpredictable
|
||||||
|
versions available from various packages.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>Resulting derivations for both builders also have two helpful
|
||||||
|
attributes, <literal>env</literal> and <literal>wrappedRuby</literal>.
|
||||||
|
The first one allows one to quickly drop into
|
||||||
|
<command>nix-shell</command> with the specified environment present.
|
||||||
|
E.g. <command>nix-shell -A sensu.env</command> would give you an
|
||||||
|
environment with Ruby preset so it has all the libraries necessary
|
||||||
|
for <literal>sensu</literal> in its paths. The second one can be
|
||||||
|
used to make derivations from custom Ruby scripts which have
|
||||||
|
<filename>Gemfile</filename>s with their dependencies specified. It is
|
||||||
|
a derivation with <command>ruby</command> wrapped so it can find all
|
||||||
|
the needed dependencies. For example, to make a derivation
|
||||||
|
<literal>my-script</literal> for a <filename>my-script.rb</filename>
|
||||||
|
(which should be placed in <filename>bin</filename>) you should run
|
||||||
|
<command>bundix</command> as specified above and then use
|
||||||
|
<literal>bundlerEnv</literal> like this:
|
||||||
|
</para>
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<![CDATA[let env = bundlerEnv {
|
<![CDATA[let env = bundlerEnv {
|
||||||
@@ -60,13 +110,9 @@ run <command>bundix</command> as specified above and then use <literal>bundlerEn
|
|||||||
|
|
||||||
in stdenv.mkDerivation {
|
in stdenv.mkDerivation {
|
||||||
name = "my-script";
|
name = "my-script";
|
||||||
|
buildInputs = [ env.wrappedRuby ];
|
||||||
buildInputs = [ env.wrapper ];
|
|
||||||
|
|
||||||
script = ./my-script.rb;
|
script = ./my-script.rb;
|
||||||
|
|
||||||
buildCommand = ''
|
buildCommand = ''
|
||||||
mkdir -p $out/bin
|
|
||||||
install -D -m755 $script $out/bin/my-script
|
install -D -m755 $script $out/bin/my-script
|
||||||
patchShebangs $out/bin/my-script
|
patchShebangs $out/bin/my-script
|
||||||
'';
|
'';
|
||||||
@@ -74,4 +120,3 @@ in stdenv.mkDerivation {
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -9,16 +9,15 @@ date: 2017-03-05
|
|||||||
To install the rust compiler and cargo put
|
To install the rust compiler and cargo put
|
||||||
|
|
||||||
```
|
```
|
||||||
rustStable.rustc
|
rust
|
||||||
rustStable.cargo
|
|
||||||
```
|
```
|
||||||
|
|
||||||
into the `environment.systemPackages` or bring them into scope with
|
into the `environment.systemPackages` or bring them into
|
||||||
`nix-shell -p rustStable.rustc -p rustStable.cargo`.
|
scope with `nix-shell -p rust`.
|
||||||
|
|
||||||
There are also `rustBeta` and `rustNightly` package sets available.
|
For daily builds (beta and nightly) use either rustup from
|
||||||
These are not updated very regulary. For daily builds use either rustup from
|
nixpkgs or use the [Rust nightlies
|
||||||
nixpkgs or use the [Rust nightlies overlay](#using-the-rust-nightlies-overlay).
|
overlay](#using-the-rust-nightlies-overlay).
|
||||||
|
|
||||||
## Packaging Rust applications
|
## Packaging Rust applications
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ buildRustPackage rec {
|
|||||||
sha256 = "0y5d1n6hkw85jb3rblcxqas2fp82h3nghssa4xqrhqnz25l799pj";
|
sha256 = "0y5d1n6hkw85jb3rblcxqas2fp82h3nghssa4xqrhqnz25l799pj";
|
||||||
};
|
};
|
||||||
|
|
||||||
depsSha256 = "0q68qyl2h6i0qsz82z840myxlnjay8p1w5z7hfyr8fqp7wgwa9cx";
|
cargoSha256 = "0q68qyl2h6i0qsz82z840myxlnjay8p1w5z7hfyr8fqp7wgwa9cx";
|
||||||
|
|
||||||
meta = with stdenv.lib; {
|
meta = with stdenv.lib; {
|
||||||
description = "A utility that combines the usability of The Silver Searcher with the raw speed of grep";
|
description = "A utility that combines the usability of The Silver Searcher with the raw speed of grep";
|
||||||
@@ -50,7 +49,7 @@ buildRustPackage rec {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`buildRustPackage` requires a `depsSha256` attribute which is computed over
|
`buildRustPackage` requires a `cargoSha256` attribute which is computed over
|
||||||
all crate sources of this package. Currently it is obtained by inserting a
|
all crate sources of this package. Currently it is obtained by inserting a
|
||||||
fake checksum into the expression and building the package once. The correct
|
fake checksum into the expression and building the package once. The correct
|
||||||
checksum can be then take from the failed build.
|
checksum can be then take from the failed build.
|
||||||
@@ -76,11 +75,11 @@ in the `~/.config/nixpkgs/overlays` directory.
|
|||||||
|
|
||||||
The latest version can be installed with the following command:
|
The latest version can be installed with the following command:
|
||||||
|
|
||||||
$ nix-env -Ai nixos.rustChannels.stable.rust
|
$ nix-env -Ai nixos.latest.rustChannels.stable.rust
|
||||||
|
|
||||||
Or using the attribute with nix-shell:
|
Or using the attribute with nix-shell:
|
||||||
|
|
||||||
$ nix-shell -p nixos.rustChannels.stable.rust
|
$ nix-shell -p nixos.latest.rustChannels.stable.rust
|
||||||
|
|
||||||
To install the beta or nightly channel, "stable" should be substituted by
|
To install the beta or nightly channel, "stable" should be substituted by
|
||||||
"nightly" or "beta", or
|
"nightly" or "beta", or
|
||||||
|
|||||||
@@ -8,15 +8,48 @@ date: 2016-06-25
|
|||||||
You'll get a vim(-your-suffix) in PATH also loading the plugins you want.
|
You'll get a vim(-your-suffix) in PATH also loading the plugins you want.
|
||||||
Loading can be deferred; see examples.
|
Loading can be deferred; see examples.
|
||||||
|
|
||||||
VAM (=vim-addon-manager) and Pathogen plugin managers are supported.
|
Vim packages, VAM (=vim-addon-manager) and Pathogen are supported to load
|
||||||
Vundle, NeoBundle could be your turn.
|
packages.
|
||||||
|
|
||||||
## dependencies by Vim plugins
|
## Custom configuration
|
||||||
|
|
||||||
|
Adding custom .vimrc lines can be done using the following code:
|
||||||
|
|
||||||
|
```
|
||||||
|
vim_configurable.customize {
|
||||||
|
name = "vim-with-plugins";
|
||||||
|
|
||||||
|
vimrcConfig.customRC = ''
|
||||||
|
set hidden
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Vim packages
|
||||||
|
|
||||||
|
To store you plugins in Vim packages the following example can be used:
|
||||||
|
|
||||||
|
```
|
||||||
|
vim_configurable.customize {
|
||||||
|
vimrcConfig.packages.myVimPackage = with pkgs.vimPlugins; {
|
||||||
|
# loaded on launch
|
||||||
|
start = [ youcompleteme fugitive ];
|
||||||
|
# manually loadable by calling `:packadd $plugin-name`
|
||||||
|
opt = [ phpCompletion elm-vim ];
|
||||||
|
# To automatically load a plugin when opening a filetype, add vimrc lines like:
|
||||||
|
# autocmd FileType php :packadd phpCompletion
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## VAM
|
||||||
|
|
||||||
|
### dependencies by Vim plugins
|
||||||
|
|
||||||
VAM introduced .json files supporting dependencies without versioning
|
VAM introduced .json files supporting dependencies without versioning
|
||||||
assuming that "using latest version" is ok most of the time.
|
assuming that "using latest version" is ok most of the time.
|
||||||
|
|
||||||
## HOWTO
|
### Example
|
||||||
|
|
||||||
First create a vim-scripts file having one plugin name per line. Example:
|
First create a vim-scripts file having one plugin name per line. Example:
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
<section><title>Installing a split package</title>
|
<section><title>Installing a split package</title>
|
||||||
<para>When installing a package via <varname>systemPackages</varname> or <command>nix-env</command> you have several options:</para>
|
<para>When installing a package via <varname>systemPackages</varname> or <command>nix-env</command> you have several options:</para>
|
||||||
<warning><para>Currently <command>nix-env</command> almost always installs all outputs until https://github.com/NixOS/nix/pull/815 gets merged.</para></warning>
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>You can install particular outputs explicitly, as each is available in the Nix language as an attribute of the package. The <varname>outputs</varname> attribute contains a list of output names.</para></listitem>
|
<listitem><para>You can install particular outputs explicitly, as each is available in the Nix language as an attribute of the package. The <varname>outputs</varname> attribute contains a list of output names.</para></listitem>
|
||||||
<listitem><para>You can let it use the default outputs. These are handled by <varname>meta.outputsToInstall</varname> attribute that contains a list of output names.</para>
|
<listitem><para>You can let it use the default outputs. These are handled by <varname>meta.outputsToInstall</varname> attribute that contains a list of output names.</para>
|
||||||
@@ -74,7 +73,7 @@
|
|||||||
|
|
||||||
<varlistentry><term><varname>
|
<varlistentry><term><varname>
|
||||||
$outputMan</varname></term><listitem><para>
|
$outputMan</varname></term><listitem><para>
|
||||||
is for man pages (except for section 3). They go to <varname>man</varname> or <varname>doc</varname> or <varname>$outputBin</varname> by default.
|
is for man pages (except for section 3). They go to <varname>man</varname> or <varname>$outputBin</varname> by default.
|
||||||
</para></listitem></varlistentry>
|
</para></listitem></varlistentry>
|
||||||
|
|
||||||
<varlistentry><term><varname>
|
<varlistentry><term><varname>
|
||||||
@@ -84,7 +83,7 @@
|
|||||||
|
|
||||||
<varlistentry><term><varname>
|
<varlistentry><term><varname>
|
||||||
$outputInfo</varname></term><listitem><para>
|
$outputInfo</varname></term><listitem><para>
|
||||||
is for info pages. They go to <varname>info</varname> or <varname>doc</varname> or <varname>$outputMan</varname> by default.
|
is for info pages. They go to <varname>info</varname> or <varname>$outputBin</varname> by default.
|
||||||
</para></listitem></varlistentry>
|
</para></listitem></varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|||||||
+64
-29
@@ -8,59 +8,88 @@
|
|||||||
overlays. Overlays are used to add layers in the fix-point used by Nixpkgs
|
overlays. Overlays are used to add layers in the fix-point used by Nixpkgs
|
||||||
to compose the set of all packages.</para>
|
to compose the set of all packages.</para>
|
||||||
|
|
||||||
|
<para>Nixpkgs can be configured with a list of overlays, which are
|
||||||
|
applied in order. This means that the order of the overlays can be significant
|
||||||
|
if multiple layers override the same package.</para>
|
||||||
|
|
||||||
<!--============================================================-->
|
<!--============================================================-->
|
||||||
|
|
||||||
<section xml:id="sec-overlays-install">
|
<section xml:id="sec-overlays-install">
|
||||||
<title>Installing Overlays</title>
|
<title>Installing overlays</title>
|
||||||
|
|
||||||
<para>The set of overlays is looked for in the following places. The
|
<para>The list of overlays is determined as follows.</para>
|
||||||
first one present is considered, and all the rest are ignored:
|
|
||||||
|
<para>If the <varname>overlays</varname> argument is not provided explicitly, we look for overlays in a path. The path
|
||||||
|
is determined as follows:
|
||||||
|
|
||||||
<orderedlist>
|
<orderedlist>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
<para>First, if an <varname>overlays</varname> argument to the nixpkgs function itself is given,
|
||||||
|
then that is used.</para>
|
||||||
|
|
||||||
<para>As an argument of the imported attribute set. When importing Nixpkgs,
|
<para>This can be passed explicitly when importing nipxkgs, for example
|
||||||
the <varname>overlays</varname> attribute argument can be set to a list of
|
<literal>import <nixpkgs> { overlays = [ overlay1 overlay2 ]; }</literal>.</para>
|
||||||
functions, which is described in <xref linkend="sec-overlays-layout"/>.</para>
|
|
||||||
|
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
<para>Otherwise, if the Nix path entry <literal><nixpkgs-overlays></literal> exists, we look for overlays
|
||||||
|
at that path, as described below.</para>
|
||||||
|
|
||||||
<para>In the directory pointed to by the Nix search path entry
|
<para>See the section on <literal>NIX_PATH</literal> in the Nix manual for more details on how to
|
||||||
<literal><nixpkgs-overlays></literal>.</para>
|
set a value for <literal><nixpkgs-overlays>.</literal></para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
<para>If one of <filename>~/.config/nixpkgs/overlays.nix</filename> and
|
||||||
<para>In the directory <filename>~/.config/nixpkgs/overlays/</filename>.</para>
|
<filename>~/.config/nixpkgs/overlays/</filename> exists, then we look for overlays at that path, as
|
||||||
|
described below. It is an error if both exist.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
</orderedlist>
|
</orderedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>For the second and third options, the directory should contain Nix expressions defining the
|
<para>If we are looking for overlays at a path, then there are two cases:
|
||||||
overlays. Each overlay can be a file, a directory containing a
|
<itemizedlist>
|
||||||
<filename>default.nix</filename>, or a symlink to one of those. The expressions should follow
|
<listitem>
|
||||||
the syntax described in <xref linkend="sec-overlays-layout"/>.</para>
|
<para>If the path is a file, then the file is imported as a Nix expression and used as the list of
|
||||||
|
overlays.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
<para>The order of the overlay layers can influence the recipe of packages if multiple layers override
|
<listitem>
|
||||||
the same recipe. In the case where overlays are loaded from a directory, they are loaded in
|
<para>If the path is a directory, then we take the content of the directory, order it
|
||||||
alphabetical order.</para>
|
lexicographically, and attempt to interpret each as an overlay by:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>Importing the file, if it is a <literal>.nix</literal> file.</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>Importing a top-level <filename>default.nix</filename> file, if it is a directory.</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>To install an overlay using the last option, you can clone the overlay's repository and add
|
<para>On a NixOS system the value of the <literal>nixpkgs.overlays</literal> option, if present,
|
||||||
a symbolic link to it in <filename>~/.config/nixpkgs/overlays/</filename> directory.</para>
|
is passed to the system Nixpkgs directly as an argument. Note that this does not affect the overlays for
|
||||||
|
non-NixOS operations (e.g. <literal>nix-env</literal>), which are looked up independently.</para>
|
||||||
|
|
||||||
|
<para>The <filename>overlays.nix</filename> option therefore provides a convenient way to use the same
|
||||||
|
overlays for a NixOS system configuration and user configuration: the same file can be used
|
||||||
|
as <filename>overlays.nix</filename> and imported as the value of <literal>nixpkgs.overlays</literal>.</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!--============================================================-->
|
<!--============================================================-->
|
||||||
|
|
||||||
<section xml:id="sec-overlays-layout">
|
<section xml:id="sec-overlays-definition">
|
||||||
<title>Overlays Layout</title>
|
<title>Defining overlays</title>
|
||||||
|
|
||||||
<para>Overlays are expressed as Nix functions which accept 2 arguments and return a set of
|
<para>Overlays are Nix functions which accept two arguments,
|
||||||
packages.</para>
|
conventionally called <varname>self</varname> and <varname>super</varname>,
|
||||||
|
and return a set of packages. For example, the following is a valid overlay.</para>
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
self: super:
|
self: super:
|
||||||
@@ -75,25 +104,31 @@ self: super:
|
|||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>The first argument, usually named <varname>self</varname>, corresponds to the final package
|
<para>The first argument (<varname>self</varname>) corresponds to the final package
|
||||||
set. You should use this set for the dependencies of all packages specified in your
|
set. You should use this set for the dependencies of all packages specified in your
|
||||||
overlay. For example, all the dependencies of <varname>rr</varname> in the example above come
|
overlay. For example, all the dependencies of <varname>rr</varname> in the example above come
|
||||||
from <varname>self</varname>, as well as the overriden dependencies used in the
|
from <varname>self</varname>, as well as the overridden dependencies used in the
|
||||||
<varname>boost</varname> override.</para>
|
<varname>boost</varname> override.</para>
|
||||||
|
|
||||||
<para>The second argument, usually named <varname>super</varname>,
|
<para>The second argument (<varname>super</varname>)
|
||||||
corresponds to the result of the evaluation of the previous stages of
|
corresponds to the result of the evaluation of the previous stages of
|
||||||
Nixpkgs. It does not contain any of the packages added by the current
|
Nixpkgs. It does not contain any of the packages added by the current
|
||||||
overlay nor any of the following overlays. This set should be used either
|
overlay, nor any of the following overlays. This set should be used either
|
||||||
to refer to packages you wish to override, or to access functions defined
|
to refer to packages you wish to override, or to access functions defined
|
||||||
in Nixpkgs. For example, the original recipe of <varname>boost</varname>
|
in Nixpkgs. For example, the original recipe of <varname>boost</varname>
|
||||||
in the above example, comes from <varname>super</varname>, as well as the
|
in the above example, comes from <varname>super</varname>, as well as the
|
||||||
<varname>callPackage</varname> function.</para>
|
<varname>callPackage</varname> function.</para>
|
||||||
|
|
||||||
<para>The value returned by this function should be a set similar to
|
<para>The value returned by this function should be a set similar to
|
||||||
<filename>pkgs/top-level/all-packages.nix</filename>, which contains
|
<filename>pkgs/top-level/all-packages.nix</filename>, containing
|
||||||
overridden and/or new packages.</para>
|
overridden and/or new packages.</para>
|
||||||
|
|
||||||
|
<para>Overlays are similar to other methods for customizing Nixpkgs, in particular
|
||||||
|
the <literal>packageOverrides</literal> attribute described in <xref linkend="sec-modify-via-packageOverrides"/>.
|
||||||
|
Indeed, <literal>packageOverrides</literal> acts as an overlay with only the
|
||||||
|
<varname>super</varname> argument. It is therefore appropriate for basic use,
|
||||||
|
but overlays are more powerful and easier to distribute.</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|||||||
+193
-45
@@ -101,7 +101,7 @@ modulesTree = [kernel]
|
|||||||
$ nix-env -i ncurses
|
$ nix-env -i ncurses
|
||||||
$ export NIX_CFLAGS_LINK=-lncurses
|
$ export NIX_CFLAGS_LINK=-lncurses
|
||||||
$ make menuconfig ARCH=<replaceable>arch</replaceable></screen>
|
$ make menuconfig ARCH=<replaceable>arch</replaceable></screen>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
@@ -111,9 +111,9 @@ $ make menuconfig ARCH=<replaceable>arch</replaceable></screen>
|
|||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
</orderedlist>
|
</orderedlist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
@@ -366,15 +366,33 @@ it. Place the resulting <filename>package.nix</filename> file into
|
|||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="sec-autojump">
|
<section xml:id="sec-shell-helpers">
|
||||||
|
|
||||||
<title>Autojump</title>
|
<title>Interactive shell helpers</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
autojump needs the shell integration to be useful but unlike other systems,
|
Some packages provide the shell integration to be more useful. But
|
||||||
nix doesn't have a standard share directory location. This is why a
|
unlike other systems, nix doesn't have a standard share directory
|
||||||
<command>autojump-share</command> script is shipped that prints the location
|
location. This is why a bunch <command>PACKAGE-share</command>
|
||||||
of the shared folder. This can then be used in the .bashrc like this:
|
scripts are shipped that print the location of the corresponding
|
||||||
|
shared folder.
|
||||||
|
|
||||||
|
Current list of such packages is as following:
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>autojump</literal>: <command>autojump-share</command>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>fzf</literal>: <command>fzf-share</command>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
E.g. <literal>autojump</literal> can then used in the .bashrc like this:
|
||||||
<screen>
|
<screen>
|
||||||
source "$(autojump-share)/autojump.bash"
|
source "$(autojump-share)/autojump.bash"
|
||||||
</screen>
|
</screen>
|
||||||
@@ -391,24 +409,24 @@ it. Place the resulting <filename>package.nix</filename> file into
|
|||||||
<title>Steam in Nix</title>
|
<title>Steam in Nix</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Steam is distributed as a <filename>.deb</filename> file, for now only
|
Steam is distributed as a <filename>.deb</filename> file, for now only
|
||||||
as an i686 package (the amd64 package only has documentation).
|
as an i686 package (the amd64 package only has documentation).
|
||||||
When unpacked, it has a script called <filename>steam</filename> that
|
When unpacked, it has a script called <filename>steam</filename> that
|
||||||
in ubuntu (their target distro) would go to <filename>/usr/bin
|
in ubuntu (their target distro) would go to <filename>/usr/bin
|
||||||
</filename>. When run for the first time, this script copies some
|
</filename>. When run for the first time, this script copies some
|
||||||
files to the user's home, which include another script that is the
|
files to the user's home, which include another script that is the
|
||||||
ultimate responsible for launching the steam binary, which is also
|
ultimate responsible for launching the steam binary, which is also
|
||||||
in $HOME.
|
in $HOME.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Nix problems and constraints:
|
Nix problems and constraints:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>We don't have <filename>/bin/bash</filename> and many
|
<listitem><para>We don't have <filename>/bin/bash</filename> and many
|
||||||
scripts point there. Similarly for <filename>/usr/bin/python</filename>
|
scripts point there. Similarly for <filename>/usr/bin/python</filename>
|
||||||
.</para></listitem>
|
.</para></listitem>
|
||||||
<listitem><para>We don't have the dynamic loader in <filename>/lib
|
<listitem><para>We don't have the dynamic loader in <filename>/lib
|
||||||
</filename>.</para></listitem>
|
</filename>.</para></listitem>
|
||||||
<listitem><para>The <filename>steam.sh</filename> script in $HOME can
|
<listitem><para>The <filename>steam.sh</filename> script in $HOME can
|
||||||
not be patched, as it is checked and rewritten by steam.</para></listitem>
|
not be patched, as it is checked and rewritten by steam.</para></listitem>
|
||||||
<listitem><para>The steam binary cannot be patched, it's also checked.</para></listitem>
|
<listitem><para>The steam binary cannot be patched, it's also checked.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
@@ -428,10 +446,10 @@ it. Place the resulting <filename>package.nix</filename> file into
|
|||||||
<title>How to play</title>
|
<title>How to play</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
For 64-bit systems it's important to have
|
For 64-bit systems it's important to have
|
||||||
<programlisting>hardware.opengl.driSupport32Bit = true;</programlisting>
|
<programlisting>hardware.opengl.driSupport32Bit = true;</programlisting>
|
||||||
in your <filename>/etc/nixos/configuration.nix</filename>. You'll also need
|
in your <filename>/etc/nixos/configuration.nix</filename>. You'll also need
|
||||||
<programlisting>hardware.pulseaudio.support32Bit = true;</programlisting>
|
<programlisting>hardware.pulseaudio.support32Bit = true;</programlisting>
|
||||||
if you are using PulseAudio - this will enable 32bit ALSA apps integration.
|
if you are using PulseAudio - this will enable 32bit ALSA apps integration.
|
||||||
To use the Steam controller, you need to add
|
To use the Steam controller, you need to add
|
||||||
<programlisting>services.udev.extraRules = ''
|
<programlisting>services.udev.extraRules = ''
|
||||||
@@ -452,31 +470,25 @@ it. Place the resulting <filename>package.nix</filename> file into
|
|||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>Steam fails to start. What do I do?</term>
|
<term>Steam fails to start. What do I do?</term>
|
||||||
<listitem><para>Try to run
|
<listitem><para>Try to run
|
||||||
<programlisting>strace steam</programlisting>
|
<programlisting>strace steam</programlisting>
|
||||||
to see what is causing steam to fail.</para></listitem>
|
to see what is causing steam to fail.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>Using the FOSS Radeon drivers</term>
|
<term>Using the FOSS Radeon or nouveau (nvidia) drivers</term>
|
||||||
<listitem><itemizedlist><listitem><para>
|
<listitem><itemizedlist>
|
||||||
The open source radeon drivers need a newer libc++ than is provided
|
<listitem><para>The <literal>newStdcpp</literal> parameter
|
||||||
by the default runtime, which leads to a crash on launch. Use
|
was removed since NixOS 17.09 and should not be needed anymore.
|
||||||
<programlisting>environment.systemPackages = [(pkgs.steam.override { newStdcpp = true; })];</programlisting>
|
</para></listitem>
|
||||||
in your config if you get an error like
|
|
||||||
<programlisting>
|
<listitem><para>
|
||||||
libGL error: unable to load driver: radeonsi_dri.so
|
Steam ships statically linked with a version of libcrypto that
|
||||||
libGL error: driver pointer missing
|
conflics with the one dynamically loaded by radeonsi_dri.so.
|
||||||
libGL error: failed to load driver: radeonsi
|
If you get the error
|
||||||
libGL error: unable to load driver: swrast_dri.so
|
<programlisting>steam.sh: line 713: 7842 Segmentation fault (core dumped)</programlisting>
|
||||||
libGL error: failed to load driver: swrast</programlisting></para></listitem>
|
have a look at <link xlink:href="https://github.com/NixOS/nixpkgs/pull/20269">this pull request</link>.
|
||||||
<listitem><para>
|
</para></listitem>
|
||||||
Steam ships statically linked with a version of libcrypto that
|
|
||||||
conflics with the one dynamically loaded by radeonsi_dri.so.
|
|
||||||
If you get the error
|
|
||||||
<programlisting>steam.sh: line 713: 7842 Segmentation fault (core dumped)</programlisting>
|
|
||||||
have a look at <link xlink:href="https://github.com/NixOS/nixpkgs/pull/20269">this pull request</link>.
|
|
||||||
</para></listitem>
|
|
||||||
|
|
||||||
</itemizedlist></listitem></varlistentry>
|
</itemizedlist></listitem></varlistentry>
|
||||||
|
|
||||||
@@ -486,7 +498,7 @@ libGL error: failed to load driver: swrast</programlisting></para></listitem>
|
|||||||
<listitem><para>
|
<listitem><para>
|
||||||
There is no java in steam chrootenv by default. If you get a message like
|
There is no java in steam chrootenv by default. If you get a message like
|
||||||
<programlisting>/home/foo/.local/share/Steam/SteamApps/common/towns/towns.sh: line 1: java: command not found</programlisting>
|
<programlisting>/home/foo/.local/share/Steam/SteamApps/common/towns/towns.sh: line 1: java: command not found</programlisting>
|
||||||
You need to add
|
You need to add
|
||||||
<programlisting> steam.override { withJava = true; };</programlisting>
|
<programlisting> steam.override { withJava = true; };</programlisting>
|
||||||
to your configuration.
|
to your configuration.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
@@ -501,14 +513,14 @@ libGL error: failed to load driver: swrast</programlisting></para></listitem>
|
|||||||
|
|
||||||
<title>steam-run</title>
|
<title>steam-run</title>
|
||||||
<para>
|
<para>
|
||||||
The FHS-compatible chroot used for steam can also be used to run
|
The FHS-compatible chroot used for steam can also be used to run
|
||||||
other linux games that expect a FHS environment.
|
other linux games that expect a FHS environment.
|
||||||
To do it, add
|
To do it, add
|
||||||
<programlisting>pkgs.(steam.override {
|
<programlisting>pkgs.(steam.override {
|
||||||
nativeOnly = true;
|
nativeOnly = true;
|
||||||
newStdcpp = true;
|
newStdcpp = true;
|
||||||
}).run</programlisting>
|
}).run</programlisting>
|
||||||
to your configuration, rebuild, and run the game with
|
to your configuration, rebuild, and run the game with
|
||||||
<programlisting>steam-run ./foo</programlisting>
|
<programlisting>steam-run ./foo</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@@ -516,4 +528,140 @@ to your configuration, rebuild, and run the game with
|
|||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section xml:id="sec-emacs">
|
||||||
|
|
||||||
|
<title>Emacs</title>
|
||||||
|
|
||||||
|
<section xml:id="sec-emacs-config">
|
||||||
|
|
||||||
|
<title>Configuring Emacs</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The Emacs package comes with some extra helpers to make it easier to
|
||||||
|
configure. <varname>emacsWithPackages</varname> allows you to manage
|
||||||
|
packages from ELPA. This means that you will not have to install
|
||||||
|
that packages from within Emacs. For instance, if you wanted to use
|
||||||
|
<literal>company</literal>, <literal>counsel</literal>,
|
||||||
|
<literal>flycheck</literal>, <literal>ivy</literal>,
|
||||||
|
<literal>magit</literal>, <literal>projectile</literal>, and
|
||||||
|
<literal>use-package</literal> you could use this as a
|
||||||
|
<filename>~/.config/nixpkgs/config.nix</filename> override:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
{
|
||||||
|
packageOverrides = pkgs: with pkgs; {
|
||||||
|
myEmacs = emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
|
||||||
|
company
|
||||||
|
counsel
|
||||||
|
flycheck
|
||||||
|
ivy
|
||||||
|
magit
|
||||||
|
projectile
|
||||||
|
use-package
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
You can install it like any other packages via <command>nix-env -iA
|
||||||
|
myEmacs</command>. However, this will only install those packages.
|
||||||
|
It will not <literal>configure</literal> them for us. To do this, we
|
||||||
|
need to provide a configuration file. Luckily, it is possible to do
|
||||||
|
this from within Nix! By modifying the above example, we can make
|
||||||
|
Emacs load a custom config file. The key is to create a package that
|
||||||
|
provide a <filename>default.el</filename> file in
|
||||||
|
<filename>/share/emacs/site-start/</filename>. Emacs knows to load
|
||||||
|
this file automatically when it starts.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
{
|
||||||
|
packageOverrides = pkgs: with pkgs; rec {
|
||||||
|
myEmacsConfig = writeText "default.el" ''
|
||||||
|
;; initialize package
|
||||||
|
|
||||||
|
(require 'package)
|
||||||
|
(package-initialize 'noactivate)
|
||||||
|
(eval-when-compile
|
||||||
|
(require 'use-package))
|
||||||
|
|
||||||
|
;; load some packages
|
||||||
|
|
||||||
|
(use-package company
|
||||||
|
:bind ("<C-tab>" . company-complete)
|
||||||
|
:diminish company-mode
|
||||||
|
:commands (company-mode global-company-mode)
|
||||||
|
:defer 1
|
||||||
|
:config
|
||||||
|
(global-company-mode))
|
||||||
|
|
||||||
|
(use-package counsel
|
||||||
|
:commands (counsel-descbinds)
|
||||||
|
:bind (([remap execute-extended-command] . counsel-M-x)
|
||||||
|
("C-x C-f" . counsel-find-file)
|
||||||
|
("C-c g" . counsel-git)
|
||||||
|
("C-c j" . counsel-git-grep)
|
||||||
|
("C-c k" . counsel-ag)
|
||||||
|
("C-x l" . counsel-locate)
|
||||||
|
("M-y" . counsel-yank-pop)))
|
||||||
|
|
||||||
|
(use-package flycheck
|
||||||
|
:defer 2
|
||||||
|
:config (global-flycheck-mode))
|
||||||
|
|
||||||
|
(use-package ivy
|
||||||
|
:defer 1
|
||||||
|
:bind (("C-c C-r" . ivy-resume)
|
||||||
|
("C-x C-b" . ivy-switch-buffer)
|
||||||
|
:map ivy-minibuffer-map
|
||||||
|
("C-j" . ivy-call))
|
||||||
|
:diminish ivy-mode
|
||||||
|
:commands ivy-mode
|
||||||
|
:config
|
||||||
|
(ivy-mode 1))
|
||||||
|
|
||||||
|
(use-package magit
|
||||||
|
:defer
|
||||||
|
:if (executable-find "git")
|
||||||
|
:bind (("C-x g" . magit-status)
|
||||||
|
("C-x G" . magit-dispatch-popup))
|
||||||
|
:init
|
||||||
|
(setq magit-completing-read-function 'ivy-completing-read))
|
||||||
|
|
||||||
|
(use-package projectile
|
||||||
|
:commands projectile-mode
|
||||||
|
:bind-keymap ("C-c p" . projectile-command-map)
|
||||||
|
:defer 5
|
||||||
|
:config
|
||||||
|
(projectile-global-mode))
|
||||||
|
'';
|
||||||
|
myEmacs = emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
|
||||||
|
(runCommand "default.el" {} ''
|
||||||
|
mkdir -p $out/share/emacs/site-lisp
|
||||||
|
cp ${myEmacsConfig} $out/share/emacs/site-lisp/default.el
|
||||||
|
'')
|
||||||
|
company
|
||||||
|
counsel
|
||||||
|
flycheck
|
||||||
|
ivy
|
||||||
|
magit
|
||||||
|
projectile
|
||||||
|
use-package
|
||||||
|
]));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
This provides a fairly full Emacs start file. It will load in
|
||||||
|
addition to the user's presonal config. You can always disable it by
|
||||||
|
passing <command>-q</command> to the Emacs command.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|||||||
+1
-1
@@ -212,7 +212,7 @@ $ nix-env -f . -iA libfoo</screen>
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Optionally commit the new package and open a pull request, or send a patch to
|
<para>Optionally commit the new package and open a pull request, or send a patch to
|
||||||
<literal>nix-dev@cs.uu.nl</literal>.</para>
|
<literal>https://groups.google.com/forum/#!forum/nix-devel</literal>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<para>The high change rate of nixpkgs make any pull request that is open for
|
<para>The high change rate of nixpkgs make any pull request that is open for
|
||||||
long enough subject to conflicts that will require extra work from the
|
long enough subject to conflicts that will require extra work from the
|
||||||
submitter or the merger. Reviewing pull requests in a timely manner and being
|
submitter or the merger. Reviewing pull requests in a timely manner and being
|
||||||
responsive to the comments is the key to avoid these. Github provides sort
|
responsive to the comments is the key to avoid these. GitHub provides sort
|
||||||
filters that can be used to see the <link
|
filters that can be used to see the <link
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc">most
|
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc">most
|
||||||
recently</link> and the <link
|
recently</link> and the <link
|
||||||
|
|||||||
+68
-22
@@ -187,11 +187,13 @@ genericBuild
|
|||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>NIX_DEBUG</varname></term>
|
<term><varname>NIX_DEBUG</varname></term>
|
||||||
<listitem><para>If set, <literal>stdenv</literal> will print some
|
<listitem><para>
|
||||||
debug information during the build. In particular, the
|
A natural number indicating how much information to log.
|
||||||
<command>gcc</command> and <command>ld</command> wrapper scripts
|
If set to 1 or higher, <literal>stdenv</literal> will print moderate debug information during the build.
|
||||||
will print out the complete command line passed to the wrapped
|
In particular, the <command>gcc</command> and <command>ld</command> wrapper scripts will print out the complete command line passed to the wrapped tools.
|
||||||
tools.</para></listitem>
|
If set to 6 or higher, the <literal>stdenv</literal> setup script will be run with <literal>set -x</literal> tracing.
|
||||||
|
If set to 7 or higher, the <command>gcc</command> and <command>ld</command> wrapper scripts will also be run with <literal>set -x</literal> tracing.
|
||||||
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
@@ -318,7 +320,13 @@ containing some shell commands to be executed, or by redefining the
|
|||||||
shell function
|
shell function
|
||||||
<varname><replaceable>name</replaceable>Phase</varname>. The former
|
<varname><replaceable>name</replaceable>Phase</varname>. The former
|
||||||
is convenient to override a phase from the derivation, while the
|
is convenient to override a phase from the derivation, while the
|
||||||
latter is convenient from a build script.</para>
|
latter is convenient from a build script.
|
||||||
|
|
||||||
|
However, typically one only wants to <emphasis>add</emphasis> some
|
||||||
|
commands to a phase, e.g. by defining <literal>postInstall</literal>
|
||||||
|
or <literal>preFixup</literal>, as skipping some of the default actions
|
||||||
|
may have unexpected consequences.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
|
||||||
<section xml:id="ssec-controlling-phases"><title>Controlling
|
<section xml:id="ssec-controlling-phases"><title>Controlling
|
||||||
@@ -634,6 +642,16 @@ script) if it exists.</para>
|
|||||||
true.</para></listitem>
|
true.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>configurePlatforms</varname></term>
|
||||||
|
<listitem><para>
|
||||||
|
By default, when cross compiling, the configure script has <option>--build=...</option> and <option>--host=...</option> passed.
|
||||||
|
Packages can instead pass <literal>[ "build" "host" "target" ]</literal> or a subset to control exactly which platform flags are passed.
|
||||||
|
Compilers and other tools should use this to also pass the target platform, for example.
|
||||||
|
Note eventually these will be passed when in native builds too, to improve determinism: build-time guessing, as is done today, is a risk of impurity.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>preConfigure</varname></term>
|
<term><varname>preConfigure</varname></term>
|
||||||
<listitem><para>Hook executed at the start of the configure
|
<listitem><para>Hook executed at the start of the configure
|
||||||
@@ -680,8 +698,14 @@ nothing.</para>
|
|||||||
<listitem><para>A list of strings passed as additional flags to
|
<listitem><para>A list of strings passed as additional flags to
|
||||||
<command>make</command>. These flags are also used by the default
|
<command>make</command>. These flags are also used by the default
|
||||||
install and check phase. For setting make flags specific to the
|
install and check phase. For setting make flags specific to the
|
||||||
build phase, use <varname>buildFlags</varname> (see
|
build phase, use <varname>buildFlags</varname> (see below).
|
||||||
below).</para></listitem>
|
|
||||||
|
<programlisting>
|
||||||
|
makeFlags = [ "PREFIX=$(out)" ];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<note><para>The flags are quoted in bash, but environment variables can
|
||||||
|
be specified by using the make syntax.</para></note></para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@@ -1137,7 +1161,7 @@ makeWrapper $out/bin/foo $wrapperfile --prefix PATH : ${lib.makeBinPath [ hello
|
|||||||
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
<varlistentry xml:id='fun-substitute'>
|
<varlistentry xml:id='fun-substitute'>
|
||||||
<term><function>substitute</function>
|
<term><function>substitute</function>
|
||||||
@@ -1156,7 +1180,7 @@ makeWrapper $out/bin/foo $wrapperfile --prefix PATH : ${lib.makeBinPath [ hello
|
|||||||
<term><option>--replace</option>
|
<term><option>--replace</option>
|
||||||
<replaceable>s1</replaceable>
|
<replaceable>s1</replaceable>
|
||||||
<replaceable>s2</replaceable></term>
|
<replaceable>s2</replaceable></term>
|
||||||
<listitem><para>Replace every occurence of the string
|
<listitem><para>Replace every occurrence of the string
|
||||||
<replaceable>s1</replaceable> by
|
<replaceable>s1</replaceable> by
|
||||||
<replaceable>s2</replaceable>.</para></listitem>
|
<replaceable>s2</replaceable>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@@ -1164,7 +1188,7 @@ makeWrapper $out/bin/foo $wrapperfile --prefix PATH : ${lib.makeBinPath [ hello
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--subst-var</option>
|
<term><option>--subst-var</option>
|
||||||
<replaceable>varName</replaceable></term>
|
<replaceable>varName</replaceable></term>
|
||||||
<listitem><para>Replace every occurence of
|
<listitem><para>Replace every occurrence of
|
||||||
<literal>@<replaceable>varName</replaceable>@</literal> by
|
<literal>@<replaceable>varName</replaceable>@</literal> by
|
||||||
the contents of the environment variable
|
the contents of the environment variable
|
||||||
<replaceable>varName</replaceable>. This is useful for
|
<replaceable>varName</replaceable>. This is useful for
|
||||||
@@ -1177,7 +1201,7 @@ makeWrapper $out/bin/foo $wrapperfile --prefix PATH : ${lib.makeBinPath [ hello
|
|||||||
<term><option>--subst-var-by</option>
|
<term><option>--subst-var-by</option>
|
||||||
<replaceable>varName</replaceable>
|
<replaceable>varName</replaceable>
|
||||||
<replaceable>s</replaceable></term>
|
<replaceable>s</replaceable></term>
|
||||||
<listitem><para>Replace every occurence of
|
<listitem><para>Replace every occurrence of
|
||||||
<literal>@<replaceable>varName</replaceable>@</literal> by
|
<literal>@<replaceable>varName</replaceable>@</literal> by
|
||||||
the string <replaceable>s</replaceable>.</para></listitem>
|
the string <replaceable>s</replaceable>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@@ -1225,7 +1249,7 @@ substitute ./foo.in ./foo.out \
|
|||||||
<term><function>substituteAll</function>
|
<term><function>substituteAll</function>
|
||||||
<replaceable>infile</replaceable>
|
<replaceable>infile</replaceable>
|
||||||
<replaceable>outfile</replaceable></term>
|
<replaceable>outfile</replaceable></term>
|
||||||
<listitem><para>Replaces every occurence of
|
<listitem><para>Replaces every occurrence of
|
||||||
<literal>@<replaceable>varName</replaceable>@</literal>, where
|
<literal>@<replaceable>varName</replaceable>@</literal>, where
|
||||||
<replaceable>varName</replaceable> is any environment variable, in
|
<replaceable>varName</replaceable> is any environment variable, in
|
||||||
<replaceable>infile</replaceable>, writing the result to
|
<replaceable>infile</replaceable>, writing the result to
|
||||||
@@ -1296,7 +1320,7 @@ someVar=$(stripHash $name)
|
|||||||
|
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
<varlistentry xml:id='fun-wrapProgram'>
|
<varlistentry xml:id='fun-wrapProgram'>
|
||||||
<term><function>wrapProgram</function>
|
<term><function>wrapProgram</function>
|
||||||
@@ -1326,12 +1350,34 @@ someVar=$(stripHash $name)
|
|||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>GCC wrapper</term>
|
<term>CC Wrapper</term>
|
||||||
<listitem><para>Adds the <filename>include</filename> subdirectory
|
<listitem>
|
||||||
of each build input to the <envar>NIX_CFLAGS_COMPILE</envar>
|
<para>
|
||||||
environment variable, and the <filename>lib</filename> and
|
CC Wrapper wraps a C toolchain for a bunch of miscellaneous purposes.
|
||||||
<filename>lib64</filename> subdirectories to
|
Specifically, a C compiler (GCC or Clang), Binutils (or the CCTools + binutils mashup when targetting Darwin), and a C standard library (glibc or Darwin's libSystem) are all fed in, and dependency finding, hardening (see below), and purity checks for each are handled by CC Wrapper.
|
||||||
<envar>NIX_LDFLAGS</envar>.</para></listitem>
|
Packages typically depend on only CC Wrapper, instead of those 3 inputs directly.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Dependency finding is undoubtedly the main task of CC wrapper.
|
||||||
|
It is currently accomplished by collecting directories of host-platform dependencies (i.e. <varname>buildInputs</varname> and <varname>nativeBuildInputs</varname>) in environment variables.
|
||||||
|
CC wrapper's setup hook causes any <filename>include</filename> subdirectory of such a dependency to be added to <envar>NIX_CFLAGS_COMPILE</envar>, and any <filename>lib</filename> and <filename>lib64</filename> subdirectories to <envar>NIX_LDFLAGS</envar>.
|
||||||
|
The setup hook itself contains some lengthy comments describing the exact convoluted mechanism by which this is accomplished.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A final task of the setup hook is defining a number of standard environment variables to tell build systems which executables full-fill which purpose.
|
||||||
|
They are defined to just be the base name of the tools, under the assumption that CC Wrapper's binaries will be on the path.
|
||||||
|
Firstly, this helps poorly-written packages, e.g. ones that look for just <command>gcc</command> when <envar>CC</envar> isn't defined yet <command>clang</command> is to be used.
|
||||||
|
Secondly, this helps packages not get confused when cross-compiling, in which case multiple CC wrappers may be simultaneous in use (targeting different platforms).
|
||||||
|
<envar>BUILD_</envar>- and <envar>TARGET_</envar>-prefixed versions of the normal environment variable are defined for the additional CC Wrappers, properly disambiguating them.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A problem with this final task is that CC Wrapper is honest and defines <envar>LD</envar> as <command>ld</command>.
|
||||||
|
Most packages, however, firstly use the C compiler for linking, secondly use <envar>LD</envar> anyways, defining it as the C compiler, and thirdly, only so define <envar>LD</envar> when it is undefined as a fallback.
|
||||||
|
This triple-threat means CC Wrapper will break those packages, as LD is already defined as the actually linker which the package won't override yet doesn't want to use.
|
||||||
|
The workaround is to define, just for the problematic package, <envar>LD</envar> as the C compiler.
|
||||||
|
A good way to do this would be <command>preConfigure = "LD=$CC"</command>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@@ -1528,7 +1574,7 @@ bin/blib.a(bios_console.o): In function `bios_handle_cup':
|
|||||||
depends on such a format string, it will need to be worked around.
|
depends on such a format string, it will need to be worked around.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>Addtionally, some warnings are enabled which might trigger build
|
<para>Additionally, some warnings are enabled which might trigger build
|
||||||
failures if compiler warnings are treated as errors in the package build.
|
failures if compiler warnings are treated as errors in the package build.
|
||||||
In this case, set <option>NIX_CFLAGS_COMPILE</option> to
|
In this case, set <option>NIX_CFLAGS_COMPILE</option> to
|
||||||
<option>-Wno-error=warning-type</option>.</para>
|
<option>-Wno-error=warning-type</option>.</para>
|
||||||
@@ -1558,7 +1604,7 @@ fcntl2.h:50:4: error: call to '__open_missing_mode' declared with attribute erro
|
|||||||
<term><varname>pic</varname></term>
|
<term><varname>pic</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Adds the <option>-fPIC</option> compiler options. This options adds
|
<para>Adds the <option>-fPIC</option> compiler options. This options adds
|
||||||
support for position independant code in shared libraries and thus making
|
support for position independent code in shared libraries and thus making
|
||||||
ASLR possible.</para>
|
ASLR possible.</para>
|
||||||
<para>Most notably, the Linux kernel, kernel modules and other code
|
<para>Most notably, the Linux kernel, kernel modules and other code
|
||||||
not running in an operating system environment like boot loaders won't
|
not running in an operating system environment like boot loaders won't
|
||||||
|
|||||||
+132
-5
@@ -61,7 +61,7 @@ $ git checkout -b 'fix/pkg-name-update'
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>Format the commit in a following way:</para>
|
<para>Format the commit in a following way:</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
(pkg-name | service-name): (from -> to | init at version | refactor | etc)
|
(pkg-name | nixos/<module>): (from -> to | init at version | refactor | etc)
|
||||||
Additional information.
|
Additional information.
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
@@ -78,19 +78,19 @@ Additional information.
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<command>firefox: 3.0 -> 3.1.1</command>
|
<command>firefox: 54.0.1 -> 55.0</command>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<command>hydra service: add bazBaz option</command>
|
<command>nixos/hydra: add bazBaz option</command>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<command>nginx service: refactor config generation</command>
|
<command>nixos/nginx: refactor config generation</command>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
@@ -196,7 +196,7 @@ Additional information.
|
|||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Write the title in format <command>(pkg-name | service): improvement</command>.
|
<para>Write the title in format <command>(pkg-name | nixos/<module>): improvement</command>.
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
@@ -223,6 +223,133 @@ Additional information.
|
|||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Pull Request Template</title>
|
||||||
|
<para>
|
||||||
|
The pull request template helps determine what steps have been made for a
|
||||||
|
contribution so far, and will help guide maintainers on the status of a
|
||||||
|
change. The motivation section of the PR should include any extra details
|
||||||
|
the title does not address and link any existing issues related to the pull
|
||||||
|
request.
|
||||||
|
</para>
|
||||||
|
<para>When a PR is created, it will be pre-populated with some checkboxes detailed below:
|
||||||
|
</para>
|
||||||
|
<section>
|
||||||
|
<title>Tested using sandboxing</title>
|
||||||
|
<para>
|
||||||
|
When sandbox builds are enabled, Nix will setup an isolated environment
|
||||||
|
for each build process. It is used to remove further hidden dependencies
|
||||||
|
set by the build environment to improve reproducibility. This includes
|
||||||
|
access to the network during the build outside of
|
||||||
|
<function>fetch*</function> functions and files outside the Nix store.
|
||||||
|
Depending on the operating system access to other resources are blocked
|
||||||
|
as well (ex. inter process communication is isolated on Linux); see <link
|
||||||
|
xlink:href="https://nixos.org/nix/manual/#description-45">build-use-sandbox</link>
|
||||||
|
in Nix manual for details.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Sandboxing is not enabled by default in Nix due to a small performance
|
||||||
|
hit on each build. In pull requests for <link
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/">nixpkgs</link> people
|
||||||
|
are asked to test builds with sandboxing enabled (see <literal>Tested
|
||||||
|
using sandboxing</literal> in the pull request template) because
|
||||||
|
in<link
|
||||||
|
xlink:href="https://nixos.org/hydra/">https://nixos.org/hydra/</link>
|
||||||
|
sandboxing is also used.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Depending if you use NixOS or other platforms you can use one of the
|
||||||
|
following methods to enable sandboxing <emphasis role="bold">before</emphasis> building the package:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<emphasis role="bold">Globally enable sandboxing on NixOS</emphasis>:
|
||||||
|
add the following to
|
||||||
|
<filename>configuration.nix</filename>
|
||||||
|
<screen>nix.useSandbox = true;</screen>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<emphasis role="bold">Globally enable sandboxing on non-NixOS platforms</emphasis>:
|
||||||
|
add the following to: <filename>/etc/nix/nix.conf</filename>
|
||||||
|
<screen>build-use-sandbox = true</screen>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<title>Built on platform(s)</title>
|
||||||
|
<para>
|
||||||
|
Many Nix packages are designed to run on multiple
|
||||||
|
platforms. As such, it's important to let the maintainer know which
|
||||||
|
platforms your changes have been tested on. It's not always practical to
|
||||||
|
test a change on all platforms, and is not required for a pull request to
|
||||||
|
be merged. Only check the systems you tested the build on in this
|
||||||
|
section.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<title>Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)</title>
|
||||||
|
<para>
|
||||||
|
Packages with automated tests are much more likely to be merged in a
|
||||||
|
timely fashion because it doesn't require as much manual testing by the
|
||||||
|
maintainer to verify the functionality of the package. If there are
|
||||||
|
existing tests for the package, they should be run to verify your changes
|
||||||
|
do not break the tests. Tests only apply to packages with NixOS modules
|
||||||
|
defined and can only be run on Linux. For more details on writing and
|
||||||
|
running tests, see the <link
|
||||||
|
xlink:href="https://nixos.org/nixos/manual/index.html#sec-nixos-tests">section
|
||||||
|
in the NixOS manual</link>.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<title>Tested compilation of all pkgs that depend on this change using <command>nox-review</command></title>
|
||||||
|
<para>
|
||||||
|
If you are updating a package's version, you can use nox to make sure all
|
||||||
|
packages that depend on the updated package still compile correctly. This
|
||||||
|
can be done using the nox utility. The <command>nox-review</command>
|
||||||
|
utility can look for and build all dependencies either based on
|
||||||
|
uncommited changes with the <literal>wip</literal> option or specifying a
|
||||||
|
github pull request number.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
review uncommitted changes:
|
||||||
|
<screen>nix-shell -p nox --run nox-review wip</screen>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
review changes from pull request number 12345:
|
||||||
|
<screen>nix-shell -p nox --run nox-review pr 12345</screen>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<title>Tested execution of all binary files (usually in <filename>./result/bin/</filename>)</title>
|
||||||
|
<para>
|
||||||
|
It's important to test any executables generated by a build when you
|
||||||
|
change or create a package in nixpkgs. This can be done by looking in
|
||||||
|
<filename>./result/bin</filename> and running any files in there, or at a
|
||||||
|
minimum, the main executable for the package. For example, if you make a change
|
||||||
|
to <package>texlive</package>, you probably would only check the binaries
|
||||||
|
associated with the change you made rather than testing all of them.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<title>Meets nixpkgs contribution standards</title>
|
||||||
|
<para>
|
||||||
|
The last checkbox is fits <link
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md">CONTRIBUTING.md</link>.
|
||||||
|
The contributing document has detailed information on standards the Nix
|
||||||
|
community has for commit messages, reviews, licensing of contributions
|
||||||
|
you make to the project, etc... Everyone should read and understand the
|
||||||
|
standards the community has for contributing before submitting a pull
|
||||||
|
request.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>Hotfixing pull requests</title>
|
<title>Hotfixing pull requests</title>
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -1,11 +1,11 @@
|
|||||||
|
{ lib }:
|
||||||
# Operations on attribute sets.
|
# Operations on attribute sets.
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (builtins) head tail length;
|
inherit (builtins) head tail length;
|
||||||
inherit (import ./trivial.nix) and or;
|
inherit (lib.trivial) and or;
|
||||||
inherit (import ./default.nix) fold;
|
inherit (lib.strings) concatStringsSep;
|
||||||
inherit (import ./strings.nix) concatStringsSep;
|
inherit (lib.lists) fold concatMap concatLists all deepSeqList;
|
||||||
inherit (import ./lists.nix) concatMap concatLists all deepSeqList;
|
|
||||||
in
|
in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|||||||
+21
-3
@@ -1,6 +1,6 @@
|
|||||||
|
{ lib }:
|
||||||
let
|
let
|
||||||
|
|
||||||
lib = import ./default.nix;
|
|
||||||
inherit (builtins) attrNames isFunction;
|
inherit (builtins) attrNames isFunction;
|
||||||
|
|
||||||
in
|
in
|
||||||
@@ -51,6 +51,24 @@ rec {
|
|||||||
else { }));
|
else { }));
|
||||||
|
|
||||||
|
|
||||||
|
/* `makeOverridable` takes a function from attribute set to attribute set and
|
||||||
|
injects `override` attibute which can be used to override arguments of
|
||||||
|
the function.
|
||||||
|
|
||||||
|
nix-repl> x = {a, b}: { result = a + b; }
|
||||||
|
|
||||||
|
nix-repl> y = lib.makeOverridable x { a = 1; b = 2; }
|
||||||
|
|
||||||
|
nix-repl> y
|
||||||
|
{ override = «lambda»; overrideDerivation = «lambda»; result = 3; }
|
||||||
|
|
||||||
|
nix-repl> y.override { a = 10; }
|
||||||
|
{ override = «lambda»; overrideDerivation = «lambda»; result = 12; }
|
||||||
|
|
||||||
|
Please refer to "Nixpkgs Contributors Guide" section
|
||||||
|
"<pkg>.overrideDerivation" to learn about `overrideDerivation` and caveats
|
||||||
|
related to its use.
|
||||||
|
*/
|
||||||
makeOverridable = f: origArgs:
|
makeOverridable = f: origArgs:
|
||||||
let
|
let
|
||||||
ff = f origArgs;
|
ff = f origArgs;
|
||||||
@@ -167,7 +185,7 @@ rec {
|
|||||||
/* Make a set of packages with a common scope. All packages called
|
/* Make a set of packages with a common scope. All packages called
|
||||||
with the provided `callPackage' will be evaluated with the same
|
with the provided `callPackage' will be evaluated with the same
|
||||||
arguments. Any package in the set may depend on any other. The
|
arguments. Any package in the set may depend on any other. The
|
||||||
`override' function allows subsequent modification of the package
|
`overrideScope' function allows subsequent modification of the package
|
||||||
set in a consistent way, i.e. all packages in the set will be
|
set in a consistent way, i.e. all packages in the set will be
|
||||||
called with the overridden packages. The package sets may be
|
called with the overridden packages. The package sets may be
|
||||||
hierarchical: the packages in the set are called with the scope
|
hierarchical: the packages in the set are called with the scope
|
||||||
@@ -177,7 +195,7 @@ rec {
|
|||||||
let self = f self // {
|
let self = f self // {
|
||||||
newScope = scope: newScope (self // scope);
|
newScope = scope: newScope (self // scope);
|
||||||
callPackage = self.newScope {};
|
callPackage = self.newScope {};
|
||||||
override = g:
|
overrideScope = g:
|
||||||
makeScope newScope
|
makeScope newScope
|
||||||
(self_: let super = f self_; in super // g super self_);
|
(self_: let super = f self_; in super // g super self_);
|
||||||
packages = f;
|
packages = f;
|
||||||
|
|||||||
+27
-1
@@ -1,4 +1,6 @@
|
|||||||
let lib = import ./default.nix;
|
{ lib }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
inherit (builtins) trace attrNamesToStr isAttrs isFunction isList isInt
|
inherit (builtins) trace attrNamesToStr isAttrs isFunction isList isInt
|
||||||
isString isBool head substring attrNames;
|
isString isBool head substring attrNames;
|
||||||
@@ -20,8 +22,32 @@ rec {
|
|||||||
traceXMLValMarked = str: x: trace (str + builtins.toXML x) x;
|
traceXMLValMarked = str: x: trace (str + builtins.toXML x) x;
|
||||||
|
|
||||||
# strict trace functions (traced structure is fully evaluated and printed)
|
# strict trace functions (traced structure is fully evaluated and printed)
|
||||||
|
|
||||||
|
/* `builtins.trace`, but the value is `builtins.deepSeq`ed first. */
|
||||||
traceSeq = x: y: trace (builtins.deepSeq x x) y;
|
traceSeq = x: y: trace (builtins.deepSeq x x) y;
|
||||||
|
|
||||||
|
/* Like `traceSeq`, but only down to depth n.
|
||||||
|
* This is very useful because lots of `traceSeq` usages
|
||||||
|
* lead to an infinite recursion.
|
||||||
|
*/
|
||||||
|
traceSeqN = depth: x: y: with lib;
|
||||||
|
let snip = v: if isList v then noQuotes "[…]" v
|
||||||
|
else if isAttrs v then noQuotes "{…}" v
|
||||||
|
else v;
|
||||||
|
noQuotes = str: v: { __pretty = const str; val = v; };
|
||||||
|
modify = n: fn: v: if (n == 0) then fn v
|
||||||
|
else if isList v then map (modify (n - 1) fn) v
|
||||||
|
else if isAttrs v then mapAttrs
|
||||||
|
(const (modify (n - 1) fn)) v
|
||||||
|
else v;
|
||||||
|
in trace (generators.toPretty { allowPrettyValues = true; }
|
||||||
|
(modify depth snip x)) y;
|
||||||
|
|
||||||
|
/* `traceSeq`, but the same value is traced and returned */
|
||||||
traceValSeq = v: traceVal (builtins.deepSeq v v);
|
traceValSeq = v: traceVal (builtins.deepSeq v v);
|
||||||
|
/* `traceValSeq` but with fixed depth */
|
||||||
|
traceValSeqN = depth: v: traceSeqN depth v v;
|
||||||
|
|
||||||
|
|
||||||
# this can help debug your code as well - designed to not produce thousands of lines
|
# this can help debug your code as well - designed to not produce thousands of lines
|
||||||
traceShowVal = x: trace (showVal x) x;
|
traceShowVal = x: trace (showVal x) x;
|
||||||
|
|||||||
+113
-42
@@ -5,56 +5,127 @@
|
|||||||
*/
|
*/
|
||||||
let
|
let
|
||||||
|
|
||||||
# trivial, often used functions
|
callLibs = file: import file { inherit lib; };
|
||||||
trivial = import ./trivial.nix;
|
|
||||||
|
|
||||||
# datatypes
|
lib = rec {
|
||||||
attrsets = import ./attrsets.nix;
|
|
||||||
lists = import ./lists.nix;
|
|
||||||
strings = import ./strings.nix;
|
|
||||||
stringsWithDeps = import ./strings-with-deps.nix;
|
|
||||||
|
|
||||||
# packaging
|
# often used, or depending on very little
|
||||||
customisation = import ./customisation.nix;
|
trivial = callLibs ./trivial.nix;
|
||||||
maintainers = import ./maintainers.nix;
|
fixedPoints = callLibs ./fixed-points.nix;
|
||||||
meta = import ./meta.nix;
|
|
||||||
sources = import ./sources.nix;
|
|
||||||
|
|
||||||
# module system
|
# datatypes
|
||||||
modules = import ./modules.nix;
|
attrsets = callLibs ./attrsets.nix;
|
||||||
options = import ./options.nix;
|
lists = callLibs ./lists.nix;
|
||||||
types = import ./types.nix;
|
strings = callLibs ./strings.nix;
|
||||||
|
stringsWithDeps = callLibs ./strings-with-deps.nix;
|
||||||
|
|
||||||
# constants
|
# packaging
|
||||||
licenses = import ./licenses.nix;
|
customisation = callLibs ./customisation.nix;
|
||||||
systems = import ./systems;
|
maintainers = callLibs ./maintainers.nix;
|
||||||
|
meta = callLibs ./meta.nix;
|
||||||
|
sources = callLibs ./sources.nix;
|
||||||
|
|
||||||
# misc
|
|
||||||
debug = import ./debug.nix;
|
|
||||||
generators = import ./generators.nix;
|
|
||||||
misc = import ./deprecated.nix;
|
|
||||||
|
|
||||||
# domain-specific
|
# module system
|
||||||
sandbox = import ./sandbox.nix;
|
modules = callLibs ./modules.nix;
|
||||||
fetchers = import ./fetchers.nix;
|
options = callLibs ./options.nix;
|
||||||
|
types = callLibs ./types.nix;
|
||||||
|
|
||||||
# Eval-time filesystem handling
|
# constants
|
||||||
filesystem = import ./filesystem.nix;
|
licenses = callLibs ./licenses.nix;
|
||||||
|
systems = callLibs ./systems;
|
||||||
|
|
||||||
in
|
# misc
|
||||||
{ inherit trivial
|
debug = callLibs ./debug.nix;
|
||||||
attrsets lists strings stringsWithDeps
|
|
||||||
customisation maintainers meta sources
|
generators = callLibs ./generators.nix;
|
||||||
modules options types
|
misc = callLibs ./deprecated.nix;
|
||||||
licenses systems
|
# domain-specific
|
||||||
debug generators misc
|
sandbox = callLibs ./sandbox.nix;
|
||||||
sandbox fetchers filesystem;
|
fetchers = callLibs ./fetchers.nix;
|
||||||
|
|
||||||
|
# Eval-time filesystem handling
|
||||||
|
filesystem = callLibs ./filesystem.nix;
|
||||||
|
|
||||||
# back-compat aliases
|
# back-compat aliases
|
||||||
platforms = systems.doubles;
|
platforms = systems.doubles;
|
||||||
}
|
|
||||||
# !!! don't include everything at top-level; perhaps only the most
|
inherit (builtins) add addErrorContext attrNames
|
||||||
# commonly used functions.
|
concatLists deepSeq elem elemAt filter genericClosure genList
|
||||||
// trivial // lists // strings // stringsWithDeps // attrsets // sources
|
getAttr hasAttr head isAttrs isBool isFunction isInt isList
|
||||||
// options // types // meta // debug // misc // modules
|
isString length lessThan listToAttrs pathExists readFile
|
||||||
// customisation
|
replaceStrings seq stringLength sub substring tail;
|
||||||
|
inherit (trivial) id const concat or and boolToString mergeAttrs
|
||||||
|
flip mapNullable inNixShell min max importJSON warn info
|
||||||
|
nixpkgsVersion mod;
|
||||||
|
|
||||||
|
inherit (fixedPoints) fix fix' extends composeExtensions
|
||||||
|
makeExtensible makeExtensibleWithCustomName;
|
||||||
|
inherit (attrsets) attrByPath hasAttrByPath setAttrByPath
|
||||||
|
getAttrFromPath attrVals attrValues catAttrs filterAttrs
|
||||||
|
filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs
|
||||||
|
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
|
||||||
|
genAttrs isDerivation toDerivation optionalAttrs
|
||||||
|
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
|
||||||
|
recursiveUpdate matchAttrs overrideExisting getOutput getBin
|
||||||
|
getLib getDev chooseDevOutputs zipWithNames zip;
|
||||||
|
inherit (lists) singleton foldr fold foldl foldl' imap0 imap1
|
||||||
|
concatMap flatten remove findSingle findFirst any all count
|
||||||
|
optional optionals toList range partition zipListsWith zipLists
|
||||||
|
reverseList listDfs toposort sort take drop sublist last init
|
||||||
|
crossLists unique intersectLists subtractLists
|
||||||
|
mutuallyExclusive;
|
||||||
|
inherit (strings) concatStrings concatMapStrings concatImapStrings
|
||||||
|
intersperse concatStringsSep concatMapStringsSep
|
||||||
|
concatImapStringsSep makeSearchPath makeSearchPathOutput
|
||||||
|
makeLibraryPath makeBinPath makePerlPath optionalString
|
||||||
|
hasPrefix hasSuffix stringToCharacters stringAsChars escape
|
||||||
|
escapeShellArg escapeShellArgs replaceChars lowerChars upperChars
|
||||||
|
toLower toUpper addContextFrom splitString removePrefix
|
||||||
|
removeSuffix versionOlder versionAtLeast getVersion nameFromURL
|
||||||
|
enableFeature fixedWidthString fixedWidthNumber isStorePath
|
||||||
|
toInt readPathsFromFile fileContents;
|
||||||
|
inherit (stringsWithDeps) textClosureList textClosureMap
|
||||||
|
noDepEntry fullDepEntry packEntry stringAfter;
|
||||||
|
inherit (customisation) overrideDerivation makeOverridable
|
||||||
|
callPackageWith callPackagesWith addPassthru hydraJob makeScope;
|
||||||
|
inherit (meta) addMetaAttrs dontDistribute setName updateName
|
||||||
|
appendToName mapDerivationAttrset lowPrio lowPrioSet hiPrio
|
||||||
|
hiPrioSet;
|
||||||
|
inherit (sources) pathType pathIsDirectory cleanSourceFilter
|
||||||
|
cleanSource sourceByRegex sourceFilesBySuffices
|
||||||
|
commitIdFromGitRepo;
|
||||||
|
inherit (modules) evalModules closeModules unifyModuleSyntax
|
||||||
|
applyIfFunction unpackSubmodule packSubmodule mergeModules
|
||||||
|
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
|
||||||
|
pushDownProperties dischargeProperties filterOverrides
|
||||||
|
sortProperties fixupOptionType mkIf mkAssert mkMerge mkOverride
|
||||||
|
mkOptionDefault mkDefault mkForce mkVMOverride mkStrict
|
||||||
|
mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions
|
||||||
|
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
|
||||||
|
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
|
||||||
|
mkAliasOptionModule doRename filterModules;
|
||||||
|
inherit (options) isOption mkEnableOption mkSinkUndeclaredOptions
|
||||||
|
mergeDefaultOption mergeOneOption mergeEqualOption getValues
|
||||||
|
getFiles optionAttrSetToDocList optionAttrSetToDocList'
|
||||||
|
scrubOptionValue literalExample showOption showFiles
|
||||||
|
unknownModule mkOption;
|
||||||
|
inherit (types) isType setType defaultTypeMerge defaultFunctor
|
||||||
|
isOptionType mkOptionType;
|
||||||
|
inherit (debug) addErrorContextToAttrs traceIf traceVal
|
||||||
|
traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq
|
||||||
|
traceValSeqN traceShowVal traceShowValMarked
|
||||||
|
showVal traceCall traceCall2 traceCall3 traceValIfNot runTests
|
||||||
|
testAllTrue strict traceCallXml attrNamesToStr;
|
||||||
|
inherit (misc) maybeEnv defaultMergeArg defaultMerge foldArgs
|
||||||
|
defaultOverridableDelayableArgs composedArgsAndFun
|
||||||
|
maybeAttrNullable maybeAttr ifEnable checkFlag getValue
|
||||||
|
checkReqs uniqList uniqListExt condConcat lazyGenericClosure
|
||||||
|
innerModifySumArgs modifySumArgs innerClosePropagation
|
||||||
|
closePropagation mapAttrsFlatten nvs setAttr setAttrMerge
|
||||||
|
mergeAttrsWithFunc mergeAttrsConcatenateValues
|
||||||
|
mergeAttrsNoOverride mergeAttrByFunc mergeAttrsByFuncDefaults
|
||||||
|
mergeAttrsByFuncDefaultsClean mergeAttrBy
|
||||||
|
prepareDerivationArgs nixType imap overridableDelayableArgs;
|
||||||
|
};
|
||||||
|
in lib
|
||||||
|
|||||||
+13
-46
@@ -1,11 +1,12 @@
|
|||||||
let lib = import ./default.nix;
|
{ lib }:
|
||||||
|
let
|
||||||
inherit (builtins) isFunction head tail isList isAttrs isInt attrNames;
|
inherit (builtins) isFunction head tail isList isAttrs isInt attrNames;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
with import ./lists.nix;
|
with lib.lists;
|
||||||
with import ./attrsets.nix;
|
with lib.attrsets;
|
||||||
with import ./strings.nix;
|
with lib.strings;
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
@@ -309,48 +310,6 @@ rec {
|
|||||||
mergeAttrsByFuncDefaults = foldl mergeAttrByFunc { inherit mergeAttrBy; };
|
mergeAttrsByFuncDefaults = foldl mergeAttrByFunc { inherit mergeAttrBy; };
|
||||||
mergeAttrsByFuncDefaultsClean = list: removeAttrs (mergeAttrsByFuncDefaults list) ["mergeAttrBy"];
|
mergeAttrsByFuncDefaultsClean = list: removeAttrs (mergeAttrsByFuncDefaults list) ["mergeAttrBy"];
|
||||||
|
|
||||||
# merge attrs based on version key into mkDerivation args, see mergeAttrBy to learn about smart merge defaults
|
|
||||||
#
|
|
||||||
# This function is best explained by an example:
|
|
||||||
#
|
|
||||||
# {version ? "2.x"}:
|
|
||||||
#
|
|
||||||
# mkDerivation (mergeAttrsByVersion "package-name" version
|
|
||||||
# { # version specific settings
|
|
||||||
# "git" = { src = ..; preConfigre = "autogen.sh"; buildInputs = [automake autoconf libtool]; };
|
|
||||||
# "2.x" = { src = ..; };
|
|
||||||
# }
|
|
||||||
# { // shared settings
|
|
||||||
# buildInputs = [ common build inputs ];
|
|
||||||
# meta = { .. }
|
|
||||||
# }
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# Please note that e.g. Eelco Dolstra usually prefers having one file for
|
|
||||||
# each version. On the other hand there are valuable additional design goals
|
|
||||||
# - readability
|
|
||||||
# - do it once only
|
|
||||||
# - try to avoid duplication
|
|
||||||
#
|
|
||||||
# Marc Weber and Michael Raskin sometimes prefer keeping older
|
|
||||||
# versions around for testing and regression tests - as long as its cheap to
|
|
||||||
# do so.
|
|
||||||
#
|
|
||||||
# Very often it just happens that the "shared" code is the bigger part.
|
|
||||||
# Then using this function might be appropriate.
|
|
||||||
#
|
|
||||||
# Be aware that its easy to cause recompilations in all versions when using
|
|
||||||
# this function - also if derivations get too complex splitting into multiple
|
|
||||||
# files is the way to go.
|
|
||||||
#
|
|
||||||
# See misc.nix -> versionedDerivation
|
|
||||||
# discussion: nixpkgs: pull/310
|
|
||||||
mergeAttrsByVersion = name: version: attrsByVersion: base:
|
|
||||||
mergeAttrsByFuncDefaultsClean [ { name = "${name}-${version}"; }
|
|
||||||
base
|
|
||||||
(maybeAttr version (throw "bad version ${version} for ${name}") attrsByVersion)
|
|
||||||
];
|
|
||||||
|
|
||||||
# sane defaults (same name as attr name so that inherit can be used)
|
# sane defaults (same name as attr name so that inherit can be used)
|
||||||
mergeAttrBy = # { buildInputs = concatList; [...]; passthru = mergeAttr; [..]; }
|
mergeAttrBy = # { buildInputs = concatList; [...]; passthru = mergeAttr; [..]; }
|
||||||
listToAttrs (map (n: nameValuePair n lib.concat)
|
listToAttrs (map (n: nameValuePair n lib.concat)
|
||||||
@@ -423,4 +382,12 @@ rec {
|
|||||||
else if isInt x then "int"
|
else if isInt x then "int"
|
||||||
else "string";
|
else "string";
|
||||||
|
|
||||||
|
/* deprecated:
|
||||||
|
|
||||||
|
For historical reasons, imap has an index starting at 1.
|
||||||
|
|
||||||
|
But for consistency with the rest of the library we want an index
|
||||||
|
starting at zero.
|
||||||
|
*/
|
||||||
|
imap = imap1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# snippets that can be shared by multiple fetchers (pkgs/build-support)
|
# snippets that can be shared by multiple fetchers (pkgs/build-support)
|
||||||
|
{ lib }:
|
||||||
{
|
{
|
||||||
|
|
||||||
proxyImpureEnvVars = [
|
proxyImpureEnvVars = [
|
||||||
|
|||||||
+20
-1
@@ -1,4 +1,23 @@
|
|||||||
{ # locateDominatingFile : RegExp
|
{ lib }:
|
||||||
|
{ # haskellPathsInDir : Path -> Map String Path
|
||||||
|
# A map of all haskell packages defined in the given path,
|
||||||
|
# identified by having a cabal file with the same name as the
|
||||||
|
# directory itself.
|
||||||
|
haskellPathsInDir = root:
|
||||||
|
let # Files in the root
|
||||||
|
root-files = builtins.attrNames (builtins.readDir root);
|
||||||
|
# Files with their full paths
|
||||||
|
root-files-with-paths =
|
||||||
|
map (file:
|
||||||
|
{ name = file; value = root + "/${file}"; }
|
||||||
|
) root-files;
|
||||||
|
# Subdirectories of the root with a cabal file.
|
||||||
|
cabal-subdirs =
|
||||||
|
builtins.filter ({ name, value }:
|
||||||
|
builtins.pathExists (value + "/${name}.cabal")
|
||||||
|
) root-files-with-paths;
|
||||||
|
in builtins.listToAttrs cabal-subdirs;
|
||||||
|
# locateDominatingFile : RegExp
|
||||||
# -> Path
|
# -> Path
|
||||||
# -> Nullable { path : Path;
|
# -> Nullable { path : Path;
|
||||||
# matches : [ MatchResults ];
|
# matches : [ MatchResults ];
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
{ ... }:
|
||||||
|
rec {
|
||||||
|
# Compute the fixed point of the given function `f`, which is usually an
|
||||||
|
# attribute set that expects its final, non-recursive representation as an
|
||||||
|
# argument:
|
||||||
|
#
|
||||||
|
# f = self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; }
|
||||||
|
#
|
||||||
|
# Nix evaluates this recursion until all references to `self` have been
|
||||||
|
# resolved. At that point, the final result is returned and `f x = x` holds:
|
||||||
|
#
|
||||||
|
# nix-repl> fix f
|
||||||
|
# { bar = "bar"; foo = "foo"; foobar = "foobar"; }
|
||||||
|
#
|
||||||
|
# Type: fix :: (a -> a) -> a
|
||||||
|
#
|
||||||
|
# See https://en.wikipedia.org/wiki/Fixed-point_combinator for further
|
||||||
|
# details.
|
||||||
|
fix = f: let x = f x; in x;
|
||||||
|
|
||||||
|
# A variant of `fix` that records the original recursive attribute set in the
|
||||||
|
# result. This is useful in combination with the `extends` function to
|
||||||
|
# implement deep overriding. See pkgs/development/haskell-modules/default.nix
|
||||||
|
# for a concrete example.
|
||||||
|
fix' = f: let x = f x // { __unfix__ = f; }; in x;
|
||||||
|
|
||||||
|
# Modify the contents of an explicitly recursive attribute set in a way that
|
||||||
|
# honors `self`-references. This is accomplished with a function
|
||||||
|
#
|
||||||
|
# g = self: super: { foo = super.foo + " + "; }
|
||||||
|
#
|
||||||
|
# that has access to the unmodified input (`super`) as well as the final
|
||||||
|
# non-recursive representation of the attribute set (`self`). `extends`
|
||||||
|
# differs from the native `//` operator insofar as that it's applied *before*
|
||||||
|
# references to `self` are resolved:
|
||||||
|
#
|
||||||
|
# nix-repl> fix (extends g f)
|
||||||
|
# { bar = "bar"; foo = "foo + "; foobar = "foo + bar"; }
|
||||||
|
#
|
||||||
|
# The name of the function is inspired by object-oriented inheritance, i.e.
|
||||||
|
# think of it as an infix operator `g extends f` that mimics the syntax from
|
||||||
|
# Java. It may seem counter-intuitive to have the "base class" as the second
|
||||||
|
# argument, but it's nice this way if several uses of `extends` are cascaded.
|
||||||
|
extends = f: rattrs: self: let super = rattrs self; in super // f self super;
|
||||||
|
|
||||||
|
# Compose two extending functions of the type expected by 'extends'
|
||||||
|
# into one where changes made in the first are available in the
|
||||||
|
# 'super' of the second
|
||||||
|
composeExtensions =
|
||||||
|
f: g: self: super:
|
||||||
|
let fApplied = f self super;
|
||||||
|
super' = super // fApplied;
|
||||||
|
in fApplied // g self super';
|
||||||
|
|
||||||
|
# Create an overridable, recursive attribute set. For example:
|
||||||
|
#
|
||||||
|
# nix-repl> obj = makeExtensible (self: { })
|
||||||
|
#
|
||||||
|
# nix-repl> obj
|
||||||
|
# { __unfix__ = «lambda»; extend = «lambda»; }
|
||||||
|
#
|
||||||
|
# nix-repl> obj = obj.extend (self: super: { foo = "foo"; })
|
||||||
|
#
|
||||||
|
# nix-repl> obj
|
||||||
|
# { __unfix__ = «lambda»; extend = «lambda»; foo = "foo"; }
|
||||||
|
#
|
||||||
|
# nix-repl> obj = obj.extend (self: super: { foo = super.foo + " + "; bar = "bar"; foobar = self.foo + self.bar; })
|
||||||
|
#
|
||||||
|
# nix-repl> obj
|
||||||
|
# { __unfix__ = «lambda»; bar = "bar"; extend = «lambda»; foo = "foo + "; foobar = "foo + bar"; }
|
||||||
|
makeExtensible = makeExtensibleWithCustomName "extend";
|
||||||
|
|
||||||
|
# Same as `makeExtensible` but the name of the extending attribute is
|
||||||
|
# customized.
|
||||||
|
makeExtensibleWithCustomName = extenderName: rattrs:
|
||||||
|
fix' rattrs // {
|
||||||
|
${extenderName} = f: makeExtensibleWithCustomName extenderName (extends f rattrs);
|
||||||
|
};
|
||||||
|
}
|
||||||
+41
-3
@@ -7,10 +7,11 @@
|
|||||||
* Tests can be found in ./tests.nix
|
* Tests can be found in ./tests.nix
|
||||||
* Documentation in the manual, #sec-generators
|
* Documentation in the manual, #sec-generators
|
||||||
*/
|
*/
|
||||||
with import ./trivial.nix;
|
{ lib }:
|
||||||
|
with (lib).trivial;
|
||||||
let
|
let
|
||||||
libStr = import ./strings.nix;
|
libStr = lib.strings;
|
||||||
libAttr = import ./attrsets.nix;
|
libAttr = lib.attrsets;
|
||||||
|
|
||||||
flipMapAttrs = flip libAttr.mapAttrs;
|
flipMapAttrs = flip libAttr.mapAttrs;
|
||||||
in
|
in
|
||||||
@@ -90,4 +91,41 @@ rec {
|
|||||||
* parsers as well.
|
* parsers as well.
|
||||||
*/
|
*/
|
||||||
toYAML = {}@args: toJSON args;
|
toYAML = {}@args: toJSON args;
|
||||||
|
|
||||||
|
/* Pretty print a value, akin to `builtins.trace`.
|
||||||
|
* Should probably be a builtin as well.
|
||||||
|
*/
|
||||||
|
toPretty = {
|
||||||
|
/* If this option is true, attrsets like { __pretty = fn; val = …; }
|
||||||
|
will use fn to convert val to a pretty printed representation.
|
||||||
|
(This means fn is type Val -> String.) */
|
||||||
|
allowPrettyValues ? false
|
||||||
|
}@args: v: with builtins;
|
||||||
|
if isInt v then toString v
|
||||||
|
else if isBool v then (if v == true then "true" else "false")
|
||||||
|
else if isString v then "\"" + v + "\""
|
||||||
|
else if null == v then "null"
|
||||||
|
else if isFunction v then
|
||||||
|
let fna = functionArgs v;
|
||||||
|
showFnas = concatStringsSep "," (libAttr.mapAttrsToList
|
||||||
|
(name: hasDefVal: if hasDefVal then "(${name})" else name)
|
||||||
|
fna);
|
||||||
|
in if fna == {} then "<λ>"
|
||||||
|
else "<λ:{${showFnas}}>"
|
||||||
|
else if isList v then "[ "
|
||||||
|
+ libStr.concatMapStringsSep " " (toPretty args) v
|
||||||
|
+ " ]"
|
||||||
|
else if isAttrs v then
|
||||||
|
# apply pretty values if allowed
|
||||||
|
if attrNames v == [ "__pretty" "val" ] && allowPrettyValues
|
||||||
|
then v.__pretty v.val
|
||||||
|
# TODO: there is probably a better representation?
|
||||||
|
else if v ? type && v.type == "derivation" then "<δ>"
|
||||||
|
else "{ "
|
||||||
|
+ libStr.concatStringsSep " " (libAttr.mapAttrsToList
|
||||||
|
(name: value:
|
||||||
|
"${toPretty args name} = ${toPretty args value};") v)
|
||||||
|
+ " }"
|
||||||
|
else "toPretty: should never happen (v = ${v})";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-9
@@ -1,7 +1,6 @@
|
|||||||
|
{ lib }:
|
||||||
let
|
let
|
||||||
|
|
||||||
lib = import ./default.nix;
|
|
||||||
|
|
||||||
spdx = lic: lic // {
|
spdx = lic: lic // {
|
||||||
url = "http://spdx.org/licenses/${lic.spdxId}";
|
url = "http://spdx.org/licenses/${lic.spdxId}";
|
||||||
};
|
};
|
||||||
@@ -45,6 +44,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = "Apple Public Source License 2.0";
|
fullName = "Apple Public Source License 2.0";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
arphicpl = {
|
||||||
|
fullName = "Arphic Public License";
|
||||||
|
url = https://www.freedesktop.org/wiki/Arphic_Public_License/;
|
||||||
|
};
|
||||||
|
|
||||||
artistic1 = spdx {
|
artistic1 = spdx {
|
||||||
spdxId = "Artistic-1.0";
|
spdxId = "Artistic-1.0";
|
||||||
fullName = "Artistic License 1.0";
|
fullName = "Artistic License 1.0";
|
||||||
@@ -170,6 +174,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = "DOC License";
|
fullName = "DOC License";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
eapl = {
|
||||||
|
fullName = "EPSON AVASYS PUBLIC LICENSE";
|
||||||
|
url = http://avasys.jp/hp/menu000000700/hpg000000603.htm;
|
||||||
|
free = false;
|
||||||
|
};
|
||||||
|
|
||||||
efl10 = spdx {
|
efl10 = spdx {
|
||||||
spdxId = "EFL-1.0";
|
spdxId = "EFL-1.0";
|
||||||
fullName = "Eiffel Forum License v1.0";
|
fullName = "Eiffel Forum License v1.0";
|
||||||
@@ -193,7 +203,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
|
|
||||||
eupl11 = spdx {
|
eupl11 = spdx {
|
||||||
spdxId = "EUPL-1.1";
|
spdxId = "EUPL-1.1";
|
||||||
fullname = "European Union Public License 1.1";
|
fullName = "European Union Public License 1.1";
|
||||||
};
|
};
|
||||||
|
|
||||||
fdl12 = spdx {
|
fdl12 = spdx {
|
||||||
@@ -206,6 +216,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = "GNU Free Documentation License v1.3";
|
fullName = "GNU Free Documentation License v1.3";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ffsl = {
|
||||||
|
fullName = "Floodgap Free Software License";
|
||||||
|
url = http://www.floodgap.com/software/ffsl/license.html;
|
||||||
|
};
|
||||||
|
|
||||||
free = {
|
free = {
|
||||||
fullName = "Unspecified free software license";
|
fullName = "Unspecified free software license";
|
||||||
};
|
};
|
||||||
@@ -266,6 +281,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
|
url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hpnd = spdx {
|
||||||
|
spdxId = "HPND";
|
||||||
|
fullName = "Historic Permission Notice and Disclaimer";
|
||||||
|
};
|
||||||
|
|
||||||
# Intel's license, seems free
|
# Intel's license, seems free
|
||||||
iasl = {
|
iasl = {
|
||||||
fullName = "iASL";
|
fullName = "iASL";
|
||||||
@@ -277,9 +297,10 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = "Independent JPEG Group License";
|
fullName = "Independent JPEG Group License";
|
||||||
};
|
};
|
||||||
|
|
||||||
inria = {
|
inria-compcert = {
|
||||||
fullName = "INRIA Non-Commercial License Agreement";
|
fullName = "INRIA Non-Commercial License Agreement for the CompCert verified compiler";
|
||||||
url = "http://compcert.inria.fr/doc/LICENSE";
|
url = "http://compcert.inria.fr/doc/LICENSE";
|
||||||
|
free = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
ipa = spdx {
|
ipa = spdx {
|
||||||
@@ -358,7 +379,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
miros = {
|
miros = {
|
||||||
fullname = "MirOS License";
|
fullName = "MirOS License";
|
||||||
url = https://opensource.org/licenses/MirOS;
|
url = https://opensource.org/licenses/MirOS;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -403,7 +424,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
url = "https://raw.githubusercontent.com/raboof/notion/master/LICENSE";
|
url = "https://raw.githubusercontent.com/raboof/notion/master/LICENSE";
|
||||||
fullName = "Notion modified LGPL";
|
fullName = "Notion modified LGPL";
|
||||||
};
|
};
|
||||||
|
|
||||||
ofl = spdx {
|
ofl = spdx {
|
||||||
spdxId = "OFL-1.1";
|
spdxId = "OFL-1.1";
|
||||||
fullName = "SIL Open Font License 1.1";
|
fullName = "SIL Open Font License 1.1";
|
||||||
@@ -531,17 +552,22 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
|||||||
fullName = "Do What The F*ck You Want To Public License";
|
fullName = "Do What The F*ck You Want To Public License";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
wxWindows = spdx {
|
||||||
|
spdxId = "WXwindows";
|
||||||
|
fullName = "wxWindows Library Licence, Version 3.1";
|
||||||
|
};
|
||||||
|
|
||||||
zlib = spdx {
|
zlib = spdx {
|
||||||
spdxId = "Zlib";
|
spdxId = "Zlib";
|
||||||
fullName = "zlib License";
|
fullName = "zlib License";
|
||||||
};
|
};
|
||||||
|
|
||||||
zpt20 = spdx { # FIXME: why zpt* instead of zpl*
|
zpl20 = spdx {
|
||||||
spdxId = "ZPL-2.0";
|
spdxId = "ZPL-2.0";
|
||||||
fullName = "Zope Public License 2.0";
|
fullName = "Zope Public License 2.0";
|
||||||
};
|
};
|
||||||
|
|
||||||
zpt21 = spdx {
|
zpl21 = spdx {
|
||||||
spdxId = "ZPL-2.1";
|
spdxId = "ZPL-2.1";
|
||||||
fullName = "Zope Public License 2.1";
|
fullName = "Zope Public License 2.1";
|
||||||
};
|
};
|
||||||
|
|||||||
+21
-7
@@ -1,6 +1,6 @@
|
|||||||
# General list operations.
|
# General list operations.
|
||||||
|
{ lib }:
|
||||||
with import ./trivial.nix;
|
with lib.trivial;
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
@@ -77,15 +77,21 @@ rec {
|
|||||||
*/
|
*/
|
||||||
foldl' = builtins.foldl' or foldl;
|
foldl' = builtins.foldl' or foldl;
|
||||||
|
|
||||||
/* Map with index
|
/* Map with index starting from 0
|
||||||
|
|
||||||
FIXME(zimbatm): why does this start to count at 1?
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
imap (i: v: "${v}-${toString i}") ["a" "b"]
|
imap0 (i: v: "${v}-${toString i}") ["a" "b"]
|
||||||
|
=> [ "a-0" "b-1" ]
|
||||||
|
*/
|
||||||
|
imap0 = f: list: genList (n: f n (elemAt list n)) (length list);
|
||||||
|
|
||||||
|
/* Map with index starting from 1
|
||||||
|
|
||||||
|
Example:
|
||||||
|
imap1 (i: v: "${v}-${toString i}") ["a" "b"]
|
||||||
=> [ "a-1" "b-2" ]
|
=> [ "a-1" "b-2" ]
|
||||||
*/
|
*/
|
||||||
imap = f: list: genList (n: f (n + 1) (elemAt list n)) (length list);
|
imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list);
|
||||||
|
|
||||||
/* Map and concatenate the result.
|
/* Map and concatenate the result.
|
||||||
|
|
||||||
@@ -471,4 +477,12 @@ rec {
|
|||||||
*/
|
*/
|
||||||
subtractLists = e: filter (x: !(elem x e));
|
subtractLists = e: filter (x: !(elem x e));
|
||||||
|
|
||||||
|
/* Test if two lists have no common element.
|
||||||
|
It should be slightly more efficient than (intersectLists a b == [])
|
||||||
|
*/
|
||||||
|
mutuallyExclusive = a: b:
|
||||||
|
(builtins.length a) == 0 ||
|
||||||
|
(!(builtins.elem (builtins.head a) b) &&
|
||||||
|
mutuallyExclusive (builtins.tail a) b);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+136
-9
@@ -1,3 +1,4 @@
|
|||||||
|
{ ...}:
|
||||||
/* List of NixOS maintainers. The format is:
|
/* List of NixOS maintainers. The format is:
|
||||||
|
|
||||||
handle = "Real Name <address@example.org>";
|
handle = "Real Name <address@example.org>";
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
acowley = "Anthony Cowley <acowley@gmail.com>";
|
acowley = "Anthony Cowley <acowley@gmail.com>";
|
||||||
adelbertc = "Adelbert Chang <adelbertc@gmail.com>";
|
adelbertc = "Adelbert Chang <adelbertc@gmail.com>";
|
||||||
adev = "Adrien Devresse <adev@adev.name>";
|
adev = "Adrien Devresse <adev@adev.name>";
|
||||||
|
adisbladis = "Adam Hose <adis@blad.is>";
|
||||||
Adjective-Object = "Maxwell Huang-Hobbs <mhuan13@gmail.com>";
|
Adjective-Object = "Maxwell Huang-Hobbs <mhuan13@gmail.com>";
|
||||||
adnelson = "Allen Nelson <ithinkican@gmail.com>";
|
adnelson = "Allen Nelson <ithinkican@gmail.com>";
|
||||||
adolfogc = "Adolfo E. García Castro <adolfo.garcia.cr@gmail.com>";
|
adolfogc = "Adolfo E. García Castro <adolfo.garcia.cr@gmail.com>";
|
||||||
@@ -29,20 +31,25 @@
|
|||||||
ak = "Alexander Kjeldaas <ak@formalprivacy.com>";
|
ak = "Alexander Kjeldaas <ak@formalprivacy.com>";
|
||||||
akaWolf = "Artjom Vejsel <akawolf0@gmail.com>";
|
akaWolf = "Artjom Vejsel <akawolf0@gmail.com>";
|
||||||
akc = "Anders Claesson <akc@akc.is>";
|
akc = "Anders Claesson <akc@akc.is>";
|
||||||
|
alexvorobiev = "Alex Vorobiev <alexander.vorobiev@gmail.com";
|
||||||
algorith = "Dries Van Daele <dries_van_daele@telenet.be>";
|
algorith = "Dries Van Daele <dries_van_daele@telenet.be>";
|
||||||
alibabzo = "Alistair Bill <alistair.bill@gmail.com>";
|
alibabzo = "Alistair Bill <alistair.bill@gmail.com>";
|
||||||
all = "Nix Committers <nix-commits@lists.science.uu.nl>";
|
all = "Nix Committers <nix-commits@lists.science.uu.nl>";
|
||||||
|
alunduil = "Alex Brandt <alunduil@alunduil.com>";
|
||||||
ambrop72 = "Ambroz Bizjak <ambrop7@gmail.com>";
|
ambrop72 = "Ambroz Bizjak <ambrop7@gmail.com>";
|
||||||
amiddelk = "Arie Middelkoop <amiddelk@gmail.com>";
|
amiddelk = "Arie Middelkoop <amiddelk@gmail.com>";
|
||||||
amiloradovsky = "Andrew Miloradovsky <miloradovsky@gmail.com>";
|
amiloradovsky = "Andrew Miloradovsky <miloradovsky@gmail.com>";
|
||||||
amorsillo = "Andrew Morsillo <andrew.morsillo@gmail.com>";
|
amorsillo = "Andrew Morsillo <andrew.morsillo@gmail.com>";
|
||||||
AndersonTorres = "Anderson Torres <torres.anderson.85@gmail.com>";
|
AndersonTorres = "Anderson Torres <torres.anderson.85@gmail.com>";
|
||||||
anderspapitto = "Anders Papitto <anderspapitto@gmail.com>";
|
anderspapitto = "Anders Papitto <anderspapitto@gmail.com>";
|
||||||
|
andir = "Andreas Rammhold <andreas@rammhold.de>";
|
||||||
andres = "Andres Loeh <ksnixos@andres-loeh.de>";
|
andres = "Andres Loeh <ksnixos@andres-loeh.de>";
|
||||||
andrewrk = "Andrew Kelley <superjoe30@gmail.com>";
|
andrewrk = "Andrew Kelley <superjoe30@gmail.com>";
|
||||||
andsild = "Anders Sildnes <andsild@gmail.com>";
|
andsild = "Anders Sildnes <andsild@gmail.com>";
|
||||||
aneeshusa = "Aneesh Agrawal <aneeshusa@gmail.com>";
|
aneeshusa = "Aneesh Agrawal <aneeshusa@gmail.com>";
|
||||||
|
ankhers = "Justin Wood <justin.k.wood@gmail.com>";
|
||||||
antono = "Antono Vasiljev <self@antono.info>";
|
antono = "Antono Vasiljev <self@antono.info>";
|
||||||
|
apeschar = "Albert Peschar <albert@peschar.net>";
|
||||||
apeyroux = "Alexandre Peyroux <alex@px.io>";
|
apeyroux = "Alexandre Peyroux <alex@px.io>";
|
||||||
ardumont = "Antoine R. Dumont <eniotna.t@gmail.com>";
|
ardumont = "Antoine R. Dumont <eniotna.t@gmail.com>";
|
||||||
aristid = "Aristid Breitkreuz <aristidb@gmail.com>";
|
aristid = "Aristid Breitkreuz <aristidb@gmail.com>";
|
||||||
@@ -59,17 +66,21 @@
|
|||||||
aycanirican = "Aycan iRiCAN <iricanaycan@gmail.com>";
|
aycanirican = "Aycan iRiCAN <iricanaycan@gmail.com>";
|
||||||
bachp = "Pascal Bach <pascal.bach@nextrem.ch>";
|
bachp = "Pascal Bach <pascal.bach@nextrem.ch>";
|
||||||
badi = "Badi' Abdul-Wahid <abdulwahidc@gmail.com>";
|
badi = "Badi' Abdul-Wahid <abdulwahidc@gmail.com>";
|
||||||
balajisivaraman = "Balaji Sivaraman<sivaraman.balaji@gmail.com>";
|
balajisivaraman = "Balaji Sivaraman <sivaraman.balaji@gmail.com>";
|
||||||
|
barrucadu = "Michael Walker <mike@barrucadu.co.uk>";
|
||||||
basvandijk = "Bas van Dijk <v.dijk.bas@gmail.com>";
|
basvandijk = "Bas van Dijk <v.dijk.bas@gmail.com>";
|
||||||
Baughn = "Svein Ove Aas <sveina@gmail.com>";
|
Baughn = "Svein Ove Aas <sveina@gmail.com>";
|
||||||
bcarrell = "Brandon Carrell <brandoncarrell@gmail.com>";
|
bcarrell = "Brandon Carrell <brandoncarrell@gmail.com>";
|
||||||
bcdarwin = "Ben Darwin <bcdarwin@gmail.com>";
|
bcdarwin = "Ben Darwin <bcdarwin@gmail.com>";
|
||||||
bdimcheff = "Brandon Dimcheff <brandon@dimcheff.com>";
|
bdimcheff = "Brandon Dimcheff <brandon@dimcheff.com>";
|
||||||
|
bendlas = "Herwig Hochleitner <herwig@bendlas.net>";
|
||||||
benley = "Benjamin Staffin <benley@gmail.com>";
|
benley = "Benjamin Staffin <benley@gmail.com>";
|
||||||
bennofs = "Benno Fünfstück <benno.fuenfstueck@gmail.com>";
|
bennofs = "Benno Fünfstück <benno.fuenfstueck@gmail.com>";
|
||||||
benwbooth = "Ben Booth <benwbooth@gmail.com>";
|
benwbooth = "Ben Booth <benwbooth@gmail.com>";
|
||||||
berdario = "Dario Bertini <berdario@gmail.com>";
|
berdario = "Dario Bertini <berdario@gmail.com>";
|
||||||
bergey = "Daniel Bergey <bergey@teallabs.org>";
|
bergey = "Daniel Bergey <bergey@teallabs.org>";
|
||||||
|
bhipple = "Benjamin Hipple <bhipple@protonmail.com>";
|
||||||
|
binarin = "Alexey Lebedeff <binarin@binarin.ru>";
|
||||||
bjg = "Brian Gough <bjg@gnu.org>";
|
bjg = "Brian Gough <bjg@gnu.org>";
|
||||||
bjornfor = "Bjørn Forsman <bjorn.forsman@gmail.com>";
|
bjornfor = "Bjørn Forsman <bjorn.forsman@gmail.com>";
|
||||||
bluescreen303 = "Mathijs Kwik <mathijs@bluescreen303.nl>";
|
bluescreen303 = "Mathijs Kwik <mathijs@bluescreen303.nl>";
|
||||||
@@ -83,25 +94,34 @@
|
|||||||
bstrik = "Berno Strik <dutchman55@gmx.com>";
|
bstrik = "Berno Strik <dutchman55@gmx.com>";
|
||||||
bzizou = "Bruno Bzeznik <Bruno@bzizou.net>";
|
bzizou = "Bruno Bzeznik <Bruno@bzizou.net>";
|
||||||
c0dehero = "CodeHero <codehero@nerdpol.ch>";
|
c0dehero = "CodeHero <codehero@nerdpol.ch>";
|
||||||
|
calbrecht = "Christian Albrecht <christian.albrecht@mayflower.de>";
|
||||||
calrama = "Moritz Maxeiner <moritz@ucworks.org>";
|
calrama = "Moritz Maxeiner <moritz@ucworks.org>";
|
||||||
calvertvl = "Victor Calvert <calvertvl@gmail.com>";
|
calvertvl = "Victor Calvert <calvertvl@gmail.com>";
|
||||||
campadrenalin = "Philip Horger <campadrenalin@gmail.com>";
|
campadrenalin = "Philip Horger <campadrenalin@gmail.com>";
|
||||||
canndrew = "Andrew Cann <shum@canndrew.org>";
|
canndrew = "Andrew Cann <shum@canndrew.org>";
|
||||||
carlsverre = "Carl Sverre <accounts@carlsverre.com>";
|
carlsverre = "Carl Sverre <accounts@carlsverre.com>";
|
||||||
|
casey = "Casey Rodarmor <casey@rodarmor.net>";
|
||||||
|
catern = "Spencer Baugh <sbaugh@catern.com>";
|
||||||
|
caugner = "Claas Augner <nixos@caugner.de>";
|
||||||
cdepillabout = "Dennis Gosnell <cdep.illabout@gmail.com>";
|
cdepillabout = "Dennis Gosnell <cdep.illabout@gmail.com>";
|
||||||
cfouche = "Chaddaï Fouché <chaddai.fouche@gmail.com>";
|
cfouche = "Chaddaï Fouché <chaddai.fouche@gmail.com>";
|
||||||
changlinli = "Changlin Li <mail@changlinli.com>";
|
changlinli = "Changlin Li <mail@changlinli.com>";
|
||||||
chaoflow = "Florian Friesdorf <flo@chaoflow.net>";
|
chaoflow = "Florian Friesdorf <flo@chaoflow.net>";
|
||||||
chattered = "Phil Scott <me@philscotted.com>";
|
chattered = "Phil Scott <me@philscotted.com>";
|
||||||
choochootrain = "Hurshal Patel <hurshal@imap.cc>";
|
choochootrain = "Hurshal Patel <hurshal@imap.cc>";
|
||||||
|
chpatrick = "Patrick Chilton <chpatrick@gmail.com>";
|
||||||
chris-martin = "Chris Martin <ch.martin@gmail.com>";
|
chris-martin = "Chris Martin <ch.martin@gmail.com>";
|
||||||
chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>";
|
chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>";
|
||||||
|
chrisrosset = "Christopher Rosset <chris@rosset.org.uk>";
|
||||||
christopherpoole = "Christopher Mark Poole <mail@christopherpoole.net>";
|
christopherpoole = "Christopher Mark Poole <mail@christopherpoole.net>";
|
||||||
|
ciil = "Simon Lackerbauer <simon@lackerbauer.com>";
|
||||||
ckampka = "Christian Kampka <christian@kampka.net>";
|
ckampka = "Christian Kampka <christian@kampka.net>";
|
||||||
|
ckauhaus = "Christian Kauhaus <christian@kauhaus.de>";
|
||||||
cko = "Christine Koppelt <christine.koppelt@gmail.com>";
|
cko = "Christine Koppelt <christine.koppelt@gmail.com>";
|
||||||
cleverca22 = "Michael Bishop <cleverca22@gmail.com>";
|
cleverca22 = "Michael Bishop <cleverca22@gmail.com>";
|
||||||
cmcdragonkai = "Roger Qiu <roger.qiu@matrix.ai>";
|
cmcdragonkai = "Roger Qiu <roger.qiu@matrix.ai>";
|
||||||
cmfwyp = "cmfwyp <cmfwyp@riseup.net>";
|
cmfwyp = "cmfwyp <cmfwyp@riseup.net>";
|
||||||
|
cobbal = "Andrew Cobb <andrew.cobb@gmail.com>";
|
||||||
coconnor = "Corey O'Connor <coreyoconnor@gmail.com>";
|
coconnor = "Corey O'Connor <coreyoconnor@gmail.com>";
|
||||||
codsl = "codsl <codsl@riseup.net>";
|
codsl = "codsl <codsl@riseup.net>";
|
||||||
codyopel = "Cody Opel <codyopel@gmail.com>";
|
codyopel = "Cody Opel <codyopel@gmail.com>";
|
||||||
@@ -116,12 +136,14 @@
|
|||||||
cryptix = "Henry Bubert <cryptix@riseup.net>";
|
cryptix = "Henry Bubert <cryptix@riseup.net>";
|
||||||
CrystalGamma = "Jona Stubbe <nixos@crystalgamma.de>";
|
CrystalGamma = "Jona Stubbe <nixos@crystalgamma.de>";
|
||||||
cstrahan = "Charles Strahan <charles@cstrahan.com>";
|
cstrahan = "Charles Strahan <charles@cstrahan.com>";
|
||||||
|
csingley = "Christopher Singley <csingley@gmail.com>";
|
||||||
cwoac = "Oliver Matthews <oliver@codersoffortune.net>";
|
cwoac = "Oliver Matthews <oliver@codersoffortune.net>";
|
||||||
DamienCassou = "Damien Cassou <damien@cassou.me>";
|
DamienCassou = "Damien Cassou <damien@cassou.me>";
|
||||||
danbst = "Danylo Hlynskyi <abcz2.uprola@gmail.com>";
|
danbst = "Danylo Hlynskyi <abcz2.uprola@gmail.com>";
|
||||||
dancek = "Hannu Hartikainen <hannu.hartikainen@gmail.com>";
|
dancek = "Hannu Hartikainen <hannu.hartikainen@gmail.com>";
|
||||||
danielfullmer = "Daniel Fullmer <danielrf12@gmail.com>";
|
danielfullmer = "Daniel Fullmer <danielrf12@gmail.com>";
|
||||||
dasuxullebt = "Christoph-Simon Senjak <christoph.senjak@googlemail.com>";
|
dasuxullebt = "Christoph-Simon Senjak <christoph.senjak@googlemail.com>";
|
||||||
|
david50407 = "David Kuo <me@davy.tw>";
|
||||||
davidak = "David Kleuker <post@davidak.de>";
|
davidak = "David Kleuker <post@davidak.de>";
|
||||||
davidrusu = "David Rusu <davidrusu.me@gmail.com>";
|
davidrusu = "David Rusu <davidrusu.me@gmail.com>";
|
||||||
davorb = "Davor Babic <davor@davor.se>";
|
davorb = "Davor Babic <davor@davor.se>";
|
||||||
@@ -129,28 +151,39 @@
|
|||||||
dbrock = "Daniel Brockman <daniel@brockman.se>";
|
dbrock = "Daniel Brockman <daniel@brockman.se>";
|
||||||
deepfire = "Kosyrev Serge <_deepfire@feelingofgreen.ru>";
|
deepfire = "Kosyrev Serge <_deepfire@feelingofgreen.ru>";
|
||||||
demin-dmitriy = "Dmitriy Demin <demindf@gmail.com>";
|
demin-dmitriy = "Dmitriy Demin <demindf@gmail.com>";
|
||||||
|
derchris = "Christian Gerbrandt <derchris@me.com>";
|
||||||
DerGuteMoritz = "Moritz Heidkamp <moritz@twoticketsplease.de>";
|
DerGuteMoritz = "Moritz Heidkamp <moritz@twoticketsplease.de>";
|
||||||
|
dermetfan = "Robin Stumm <serverkorken@gmail.com>";
|
||||||
DerTim1 = "Tim Digel <tim.digel@active-group.de>";
|
DerTim1 = "Tim Digel <tim.digel@active-group.de>";
|
||||||
desiderius = "Didier J. Devroye <didier@devroye.name>";
|
desiderius = "Didier J. Devroye <didier@devroye.name>";
|
||||||
devhell = "devhell <\"^\"@regexmail.net>";
|
devhell = "devhell <\"^\"@regexmail.net>";
|
||||||
dezgeg = "Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>";
|
dezgeg = "Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>";
|
||||||
|
dfordivam = "Divam <dfordivam+nixpkgs@gmail.com>";
|
||||||
dfoxfranke = "Daniel Fox Franke <dfoxfranke@gmail.com>";
|
dfoxfranke = "Daniel Fox Franke <dfoxfranke@gmail.com>";
|
||||||
dgonyeo = "Derek Gonyeo <derek@gonyeo.com>";
|
dgonyeo = "Derek Gonyeo <derek@gonyeo.com>";
|
||||||
dipinhora = "Dipin Hora <dipinhora+github@gmail.com>";
|
dipinhora = "Dipin Hora <dipinhora+github@gmail.com>";
|
||||||
|
disassembler = "Samuel Leathers <disasm@gmail.com>";
|
||||||
|
dizfer = "David Izquierdo <david@izquierdofernandez.com>";
|
||||||
dmalikov = "Dmitry Malikov <malikov.d.y@gmail.com>";
|
dmalikov = "Dmitry Malikov <malikov.d.y@gmail.com>";
|
||||||
DmitryTsygankov = "Dmitry Tsygankov <dmitry.tsygankov@gmail.com>";
|
DmitryTsygankov = "Dmitry Tsygankov <dmitry.tsygankov@gmail.com>";
|
||||||
dmjio = "David Johnson <djohnson.m@gmail.com>";
|
dmjio = "David Johnson <djohnson.m@gmail.com>";
|
||||||
dochang = "Desmond O. Chang <dochang@gmail.com>";
|
dochang = "Desmond O. Chang <dochang@gmail.com>";
|
||||||
domenkozar = "Domen Kozar <domen@dev.si>";
|
domenkozar = "Domen Kozar <domen@dev.si>";
|
||||||
|
dotlambda = "Robert Schütz <rschuetz17@gmail.com>";
|
||||||
doublec = "Chris Double <chris.double@double.co.nz>";
|
doublec = "Chris Double <chris.double@double.co.nz>";
|
||||||
dpaetzel = "David Pätzel <david.a.paetzel@gmail.com>";
|
dpaetzel = "David Pätzel <david.a.paetzel@gmail.com>";
|
||||||
|
dpflug = "David Pflug <david@pflug.email>";
|
||||||
drets = "Dmytro Rets <dmitryrets@gmail.com>";
|
drets = "Dmytro Rets <dmitryrets@gmail.com>";
|
||||||
drewkett = "Andrew Burkett <burkett.andrew@gmail.com>";
|
drewkett = "Andrew Burkett <burkett.andrew@gmail.com>";
|
||||||
dsferruzza = "David Sferruzza <david.sferruzza@gmail.com>";
|
dsferruzza = "David Sferruzza <david.sferruzza@gmail.com>";
|
||||||
dtzWill = "Will Dietz <nix@wdtz.org>";
|
dtzWill = "Will Dietz <nix@wdtz.org>";
|
||||||
|
dupgit = "Olivier Delhomme <olivier.delhomme@free.fr>";
|
||||||
|
dywedir = "Vladyslav M. <dywedir@protonmail.ch>";
|
||||||
e-user = "Alexander Kahl <nixos@sodosopa.io>";
|
e-user = "Alexander Kahl <nixos@sodosopa.io>";
|
||||||
ebzzry = "Rommel Martinez <ebzzry@gmail.com>";
|
earldouglas = "James Earl Douglas <james@earldouglas.com>";
|
||||||
|
ebzzry = "Rommel Martinez <ebzzry@ebzzry.io>";
|
||||||
edanaher = "Evan Danaher <nixos@edanaher.net>";
|
edanaher = "Evan Danaher <nixos@edanaher.net>";
|
||||||
|
edef = "edef <edef@edef.eu>";
|
||||||
ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>";
|
ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>";
|
||||||
eduarrrd = "Eduard Bachmakov <e.bachmakov@gmail.com>";
|
eduarrrd = "Eduard Bachmakov <e.bachmakov@gmail.com>";
|
||||||
edwtjo = "Edward Tjörnhammar <ed@cflags.cc>";
|
edwtjo = "Edward Tjörnhammar <ed@cflags.cc>";
|
||||||
@@ -158,22 +191,31 @@
|
|||||||
ehegnes = "Eric Hegnes <eric.hegnes@gmail.com>";
|
ehegnes = "Eric Hegnes <eric.hegnes@gmail.com>";
|
||||||
ehmry = "Emery Hemingway <emery@vfemail.net>";
|
ehmry = "Emery Hemingway <emery@vfemail.net>";
|
||||||
eikek = "Eike Kettner <eike.kettner@posteo.de>";
|
eikek = "Eike Kettner <eike.kettner@posteo.de>";
|
||||||
|
ekleog = "Leo Gaspard <leo@gaspard.io>";
|
||||||
elasticdog = "Aaron Bull Schaefer <aaron@elasticdog.com>";
|
elasticdog = "Aaron Bull Schaefer <aaron@elasticdog.com>";
|
||||||
eleanor = "Dejan Lukan <dejan@proteansec.com>";
|
eleanor = "Dejan Lukan <dejan@proteansec.com>";
|
||||||
|
elijahcaine = "Elijah Caine <elijahcainemv@gmail.com>";
|
||||||
elitak = "Eric Litak <elitak@gmail.com>";
|
elitak = "Eric Litak <elitak@gmail.com>";
|
||||||
ellis = "Ellis Whitehead <nixos@ellisw.net>";
|
ellis = "Ellis Whitehead <nixos@ellisw.net>";
|
||||||
eperuffo = "Emanuele Peruffo <info@emanueleperuffo.com>";
|
eperuffo = "Emanuele Peruffo <info@emanueleperuffo.com>";
|
||||||
epitrochoid = "Mabry Cervin <mpcervin@uncg.edu>";
|
epitrochoid = "Mabry Cervin <mpcervin@uncg.edu>";
|
||||||
|
eqyiel = "Ruben Maher <r@rkm.id.au>";
|
||||||
ericbmerritt = "Eric Merritt <eric@afiniate.com>";
|
ericbmerritt = "Eric Merritt <eric@afiniate.com>";
|
||||||
ericsagnes = "Eric Sagnes <eric.sagnes@gmail.com>";
|
ericsagnes = "Eric Sagnes <eric.sagnes@gmail.com>";
|
||||||
|
erictapen = "Justin Humm <justin.humm@posteo.de>";
|
||||||
erikryb = "Erik Rybakken <erik.rybakken@math.ntnu.no>";
|
erikryb = "Erik Rybakken <erik.rybakken@math.ntnu.no>";
|
||||||
ertes = "Ertugrul Söylemez <esz@posteo.de>";
|
ertes = "Ertugrul Söylemez <esz@posteo.de>";
|
||||||
ethercrow = "Dmitry Ivanov <ethercrow@gmail.com>";
|
ethercrow = "Dmitry Ivanov <ethercrow@gmail.com>";
|
||||||
|
etu = "Elis Hirwing <elis@hirwing.se>";
|
||||||
exi = "Reno Reckling <nixos@reckling.org>";
|
exi = "Reno Reckling <nixos@reckling.org>";
|
||||||
exlevan = "Alexey Levan <exlevan@gmail.com>";
|
exlevan = "Alexey Levan <exlevan@gmail.com>";
|
||||||
expipiplus1 = "Joe Hermaszewski <nix@monoid.al>";
|
expipiplus1 = "Joe Hermaszewski <nix@monoid.al>";
|
||||||
fadenb = "Tristan Helmich <tristan.helmich+nixos@gmail.com>";
|
fadenb = "Tristan Helmich <tristan.helmich+nixos@gmail.com>";
|
||||||
falsifian = "James Cook <james.cook@utoronto.ca>";
|
falsifian = "James Cook <james.cook@utoronto.ca>";
|
||||||
|
fare = "Francois-Rene Rideau <fahree@gmail.com>";
|
||||||
|
fgaz = "Francesco Gazzetta <francygazz@gmail.com>";
|
||||||
|
flokli = "Florian Klink <flokli@flokli.de>";
|
||||||
|
florianjacob = "Florian Jacob <projects+nixos@florianjacob.de>";
|
||||||
flosse = "Markus Kohlhase <mail@markus-kohlhase.de>";
|
flosse = "Markus Kohlhase <mail@markus-kohlhase.de>";
|
||||||
fluffynukeit = "Daniel Austin <dan@fluffynukeit.com>";
|
fluffynukeit = "Daniel Austin <dan@fluffynukeit.com>";
|
||||||
fmthoma = "Franz Thoma <f.m.thoma@googlemail.com>";
|
fmthoma = "Franz Thoma <f.m.thoma@googlemail.com>";
|
||||||
@@ -189,14 +231,18 @@
|
|||||||
fuuzetsu = "Mateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk>";
|
fuuzetsu = "Mateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk>";
|
||||||
fuzzy-id = "Thomas Bach <hacking+nixos@babibo.de>";
|
fuzzy-id = "Thomas Bach <hacking+nixos@babibo.de>";
|
||||||
fxfactorial = "Edgar Aroutiounian <edgar.factorial@gmail.com>";
|
fxfactorial = "Edgar Aroutiounian <edgar.factorial@gmail.com>";
|
||||||
|
gabesoft = "Gabriel Adomnicai <gabesoft@gmail.com>";
|
||||||
gal_bolle = "Florent Becker <florent.becker@ens-lyon.org>";
|
gal_bolle = "Florent Becker <florent.becker@ens-lyon.org>";
|
||||||
garbas = "Rok Garbas <rok@garbas.si>";
|
garbas = "Rok Garbas <rok@garbas.si>";
|
||||||
garrison = "Jim Garrison <jim@garrison.cc>";
|
garrison = "Jim Garrison <jim@garrison.cc>";
|
||||||
gavin = "Gavin Rogers <gavin@praxeology.co.uk>";
|
gavin = "Gavin Rogers <gavin@praxeology.co.uk>";
|
||||||
gebner = "Gabriel Ebner <gebner@gebner.org>";
|
gebner = "Gabriel Ebner <gebner@gebner.org>";
|
||||||
|
geistesk = "Alvar Penning <post@0x21.biz>";
|
||||||
|
georgewhewell = "George Whewell <georgerw@gmail.com>";
|
||||||
gilligan = "Tobias Pflug <tobias.pflug@gmail.com>";
|
gilligan = "Tobias Pflug <tobias.pflug@gmail.com>";
|
||||||
giogadi = "Luis G. Torres <lgtorres42@gmail.com>";
|
giogadi = "Luis G. Torres <lgtorres42@gmail.com>";
|
||||||
gleber = "Gleb Peregud <gleber.p@gmail.com>";
|
gleber = "Gleb Peregud <gleber.p@gmail.com>";
|
||||||
|
glenns = "Glenn Searby <glenn.searby@gmail.com>";
|
||||||
globin = "Robin Gloster <mail@glob.in>";
|
globin = "Robin Gloster <mail@glob.in>";
|
||||||
gnidorah = "Alex Ivanov <yourbestfriend@opmbx.org>";
|
gnidorah = "Alex Ivanov <yourbestfriend@opmbx.org>";
|
||||||
goibhniu = "Cillian de Róiste <cillian.deroiste@gmail.com>";
|
goibhniu = "Cillian de Róiste <cillian.deroiste@gmail.com>";
|
||||||
@@ -204,70 +250,92 @@
|
|||||||
goodrone = "Andrew Trachenko <goodrone@gmail.com>";
|
goodrone = "Andrew Trachenko <goodrone@gmail.com>";
|
||||||
gpyh = "Yacine Hmito <yacine.hmito@gmail.com>";
|
gpyh = "Yacine Hmito <yacine.hmito@gmail.com>";
|
||||||
grahamc = "Graham Christensen <graham@grahamc.com>";
|
grahamc = "Graham Christensen <graham@grahamc.com>";
|
||||||
|
grburst = "Julius Elias <grburst@openmailbox.org>";
|
||||||
gridaphobe = "Eric Seidel <eric@seidel.io>";
|
gridaphobe = "Eric Seidel <eric@seidel.io>";
|
||||||
guibert = "David Guibert <david.guibert@gmail.com>";
|
guibert = "David Guibert <david.guibert@gmail.com>";
|
||||||
|
guibou = "Guillaume Bouchard <guillaum.bouchard@gmail.com>";
|
||||||
guillaumekoenig = "Guillaume Koenig <guillaume.edward.koenig@gmail.com>";
|
guillaumekoenig = "Guillaume Koenig <guillaume.edward.koenig@gmail.com>";
|
||||||
guyonvarch = "Joris Guyonvarch <joris@guyonvarch.me>";
|
guyonvarch = "Joris Guyonvarch <joris@guyonvarch.me>";
|
||||||
hakuch = "Jesse Haber-Kucharsky <hakuch@gmail.com>";
|
hakuch = "Jesse Haber-Kucharsky <hakuch@gmail.com>";
|
||||||
|
hamhut1066 = "Hamish Hutchings <github@hamhut1066.com>";
|
||||||
havvy = "Ryan Scheel <ryan.havvy@gmail.com>";
|
havvy = "Ryan Scheel <ryan.havvy@gmail.com>";
|
||||||
hbunke = "Hendrik Bunke <bunke.hendrik@gmail.com>";
|
hbunke = "Hendrik Bunke <bunke.hendrik@gmail.com>";
|
||||||
hce = "Hans-Christian Esperer <hc@hcesperer.org>";
|
hce = "Hans-Christian Esperer <hc@hcesperer.org>";
|
||||||
|
hectorj = "Hector Jusforgues <hector.jusforgues+nixos@gmail.com>";
|
||||||
heel = "Sergii Paryzhskyi <parizhskiy@gmail.com>";
|
heel = "Sergii Paryzhskyi <parizhskiy@gmail.com>";
|
||||||
henrytill = "Henry Till <henrytill@gmail.com>";
|
henrytill = "Henry Till <henrytill@gmail.com>";
|
||||||
|
hhm = "hhm <heehooman+nixpkgs@gmail.com>";
|
||||||
hinton = "Tom Hinton <t@larkery.com>";
|
hinton = "Tom Hinton <t@larkery.com>";
|
||||||
|
hodapp = "Chris Hodapp <hodapp87@gmail.com>";
|
||||||
hrdinka = "Christoph Hrdinka <c.nix@hrdinka.at>";
|
hrdinka = "Christoph Hrdinka <c.nix@hrdinka.at>";
|
||||||
|
htr = "Hugo Tavares Reis <hugo@linux.com>";
|
||||||
iand675 = "Ian Duncan <ian@iankduncan.com>";
|
iand675 = "Ian Duncan <ian@iankduncan.com>";
|
||||||
ianwookim = "Ian-Woo Kim <ianwookim@gmail.com>";
|
ianwookim = "Ian-Woo Kim <ianwookim@gmail.com>";
|
||||||
|
iblech = "Ingo Blechschmidt <iblech@speicherleck.de>";
|
||||||
igsha = "Igor Sharonov <igor.sharonov@gmail.com>";
|
igsha = "Igor Sharonov <igor.sharonov@gmail.com>";
|
||||||
ikervagyok = "Balázs Lengyel <ikervagyok@gmail.com>";
|
ikervagyok = "Balázs Lengyel <ikervagyok@gmail.com>";
|
||||||
infinisil = "Silvan Mosberger <infinisil@icloud.com";
|
infinisil = "Silvan Mosberger <infinisil@icloud.com>";
|
||||||
|
ironpinguin = "Michele Catalano <michele@catalano.de>";
|
||||||
ivan-tkatchev = "Ivan Tkatchev <tkatchev@gmail.com>";
|
ivan-tkatchev = "Ivan Tkatchev <tkatchev@gmail.com>";
|
||||||
j-keck = "Jürgen Keck <jhyphenkeck@gmail.com>";
|
j-keck = "Jürgen Keck <jhyphenkeck@gmail.com>";
|
||||||
jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>";
|
jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>";
|
||||||
|
jammerful = "jammerful <jammerful@gmail.com>";
|
||||||
jansol = "Jan Solanti <jan.solanti@paivola.fi>";
|
jansol = "Jan Solanti <jan.solanti@paivola.fi>";
|
||||||
javaguirre = "Javier Aguirre <contacto@javaguirre.net>";
|
javaguirre = "Javier Aguirre <contacto@javaguirre.net>";
|
||||||
jb55 = "William Casarin <bill@casarin.me>";
|
jb55 = "William Casarin <jb55@jb55.com>";
|
||||||
jbedo = "Justin Bedő <cu@cua0.org>";
|
jbedo = "Justin Bedő <cu@cua0.org>";
|
||||||
jcumming = "Jack Cummings <jack@mudshark.org>";
|
jcumming = "Jack Cummings <jack@mudshark.org>";
|
||||||
jdagilliland = "Jason Gilliland <jdagilliland@gmail.com>";
|
jdagilliland = "Jason Gilliland <jdagilliland@gmail.com>";
|
||||||
jefdaj = "Jeffrey David Johnson <jefdaj@gmail.com>";
|
jefdaj = "Jeffrey David Johnson <jefdaj@gmail.com>";
|
||||||
|
jensbin = "Jens Binkert <jensbin@protonmail.com>";
|
||||||
jerith666 = "Matt McHenry <github@matt.mchenryfamily.org>";
|
jerith666 = "Matt McHenry <github@matt.mchenryfamily.org>";
|
||||||
jfb = "James Felix Black <james@yamtime.com>";
|
jfb = "James Felix Black <james@yamtime.com>";
|
||||||
|
jfrankenau = "Johannes Frankenau <johannes@frankenau.net>";
|
||||||
jgeerds = "Jascha Geerds <jascha@jgeerds.name>";
|
jgeerds = "Jascha Geerds <jascha@jgeerds.name>";
|
||||||
jgertm = "Tim Jaeger <jger.tm@gmail.com>";
|
jgertm = "Tim Jaeger <jger.tm@gmail.com>";
|
||||||
jgillich = "Jakob Gillich <jakob@gillich.me>";
|
jgillich = "Jakob Gillich <jakob@gillich.me>";
|
||||||
jhhuh = "Ji-Haeng Huh <jhhuh.note@gmail.com>";
|
jhhuh = "Ji-Haeng Huh <jhhuh.note@gmail.com>";
|
||||||
jirkamarsik = "Jirka Marsik <jiri.marsik89@gmail.com>";
|
jirkamarsik = "Jirka Marsik <jiri.marsik89@gmail.com>";
|
||||||
jlesquembre = "José Luis Lafuente <jl@lafuente.me>";
|
jlesquembre = "José Luis Lafuente <jl@lafuente.me>";
|
||||||
|
jluttine = "Jaakko Luttinen <jaakko.luttinen@iki.fi>";
|
||||||
joachifm = "Joachim Fasting <joachifm@fastmail.fm>";
|
joachifm = "Joachim Fasting <joachifm@fastmail.fm>";
|
||||||
joamaki = "Jussi Maki <joamaki@gmail.com>";
|
joamaki = "Jussi Maki <joamaki@gmail.com>";
|
||||||
joelmo = "Joel Moberg <joel.moberg@gmail.com>";
|
joelmo = "Joel Moberg <joel.moberg@gmail.com>";
|
||||||
joelteon = "Joel Taylor <me@joelt.io>";
|
joelteon = "Joel Taylor <me@joelt.io>";
|
||||||
johbo = "Johannes Bornhold <johannes@bornhold.name>";
|
johbo = "Johannes Bornhold <johannes@bornhold.name>";
|
||||||
|
johnmh = "John M. Harris, Jr. <johnmh@openblox.org>";
|
||||||
|
johnramsden = "John Ramsden <johnramsden@riseup.net>";
|
||||||
joko = "Ioannis Koutras <ioannis.koutras@gmail.com>";
|
joko = "Ioannis Koutras <ioannis.koutras@gmail.com>";
|
||||||
jonafato = "Jon Banafato <jon@jonafato.com>";
|
jonafato = "Jon Banafato <jon@jonafato.com>";
|
||||||
jpbernardy = "Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com>";
|
joncojonathan = "Jonathan Haddock <joncojonathan@gmail.com>";
|
||||||
jpierre03 = "Jean-Pierre PRUNARET <nix@prunetwork.fr>";
|
jpierre03 = "Jean-Pierre PRUNARET <nix@prunetwork.fr>";
|
||||||
jpotier = "Martin Potier <jpo.contributes.to.nixos@marvid.fr>";
|
jpotier = "Martin Potier <jpo.contributes.to.nixos@marvid.fr>";
|
||||||
jraygauthier = "Raymond Gauthier <jraygauthier@gmail.com>";
|
jraygauthier = "Raymond Gauthier <jraygauthier@gmail.com>";
|
||||||
|
jtojnar = "Jan Tojnar <jtojnar@gmail.com>";
|
||||||
juliendehos = "Julien Dehos <dehos@lisic.univ-littoral.fr>";
|
juliendehos = "Julien Dehos <dehos@lisic.univ-littoral.fr>";
|
||||||
jwiegley = "John Wiegley <johnw@newartisans.com>";
|
jwiegley = "John Wiegley <johnw@newartisans.com>";
|
||||||
jwilberding = "Jordan Wilberding <jwilberding@afiniate.com>";
|
jwilberding = "Jordan Wilberding <jwilberding@afiniate.com>";
|
||||||
|
jyp = "Jean-Philippe Bernardy <jeanphilippe.bernardy@gmail.com>";
|
||||||
jzellner = "Jeff Zellner <jeffz@eml.cc>";
|
jzellner = "Jeff Zellner <jeffz@eml.cc>";
|
||||||
kaiha = "Kai Harries <kai.harries@gmail.com>";
|
kaiha = "Kai Harries <kai.harries@gmail.com>";
|
||||||
kamilchm = "Kamil Chmielewski <kamil.chm@gmail.com>";
|
kamilchm = "Kamil Chmielewski <kamil.chm@gmail.com>";
|
||||||
kampfschlaefer = "Arnold Krille <arnold@arnoldarts.de>";
|
kampfschlaefer = "Arnold Krille <arnold@arnoldarts.de>";
|
||||||
|
kentjames = "James Kent <jameschristopherkent@gmail.com";
|
||||||
kevincox = "Kevin Cox <kevincox@kevincox.ca>";
|
kevincox = "Kevin Cox <kevincox@kevincox.ca>";
|
||||||
khumba = "Bryan Gardiner <bog@khumba.net>";
|
khumba = "Bryan Gardiner <bog@khumba.net>";
|
||||||
KibaFox = "Kiba Fox <kiba.fox@foxypossibilities.com>";
|
KibaFox = "Kiba Fox <kiba.fox@foxypossibilities.com>";
|
||||||
kierdavis = "Kier Davis <kierdavis@gmail.com>";
|
kierdavis = "Kier Davis <kierdavis@gmail.com>";
|
||||||
|
kiloreux = "Kiloreux Emperex <kiloreux@gmail.com>";
|
||||||
kkallio = "Karn Kallio <tierpluspluslists@gmail.com>";
|
kkallio = "Karn Kallio <tierpluspluslists@gmail.com>";
|
||||||
knedlsepp = "Josef Kemetmüller <josef.kemetmueller@gmail.com>";
|
knedlsepp = "Josef Kemetmüller <josef.kemetmueller@gmail.com>";
|
||||||
|
konimex = "Muhammad Herdiansyah <herdiansyah@netc.eu>";
|
||||||
koral = "Koral <koral@mailoo.org>";
|
koral = "Koral <koral@mailoo.org>";
|
||||||
kovirobi = "Kovacsics Robert <kovirobi@gmail.com>";
|
kovirobi = "Kovacsics Robert <kovirobi@gmail.com>";
|
||||||
|
kquick = "Kevin Quick <quick@sparq.org>";
|
||||||
kragniz = "Louis Taylor <louis@kragniz.eu>";
|
kragniz = "Louis Taylor <louis@kragniz.eu>";
|
||||||
kristoff3r = "Kristoffer Søholm <k.soeholm@gmail.com>";
|
kristoff3r = "Kristoffer Søholm <k.soeholm@gmail.com>";
|
||||||
ktosiek = "Tomasz Kontusz <tomasz.kontusz@gmail.com>";
|
ktosiek = "Tomasz Kontusz <tomasz.kontusz@gmail.com>";
|
||||||
|
kuznero = "Roman Kuznetsov <roman@kuznero.com>";
|
||||||
lassulus = "Lassulus <lassulus@gmail.com>";
|
lassulus = "Lassulus <lassulus@gmail.com>";
|
||||||
layus = "Guillaume Maudoux <layus.on@gmail.com>";
|
layus = "Guillaume Maudoux <layus.on@gmail.com>";
|
||||||
ldesgoui = "Lucas Desgouilles <ldesgoui@gmail.com>";
|
ldesgoui = "Lucas Desgouilles <ldesgoui@gmail.com>";
|
||||||
@@ -283,16 +351,21 @@
|
|||||||
lihop = "Leroy Hopson <nixos@leroy.geek.nz>";
|
lihop = "Leroy Hopson <nixos@leroy.geek.nz>";
|
||||||
linquize = "Linquize <linquize@yahoo.com.hk>";
|
linquize = "Linquize <linquize@yahoo.com.hk>";
|
||||||
linus = "Linus Arver <linusarver@gmail.com>";
|
linus = "Linus Arver <linusarver@gmail.com>";
|
||||||
|
lluchs = "Lukas Werling <lukas.werling@gmail.com>";
|
||||||
lnl7 = "Daiderd Jordan <daiderd@gmail.com>";
|
lnl7 = "Daiderd Jordan <daiderd@gmail.com>";
|
||||||
loskutov = "Ignat Loskutov <ignat.loskutov@gmail.com>";
|
loskutov = "Ignat Loskutov <ignat.loskutov@gmail.com>";
|
||||||
lovek323 = "Jason O'Conal <jason@oconal.id.au>";
|
lovek323 = "Jason O'Conal <jason@oconal.id.au>";
|
||||||
lowfatcomputing = "Andreas Wagner <andreas.wagner@lowfatcomputing.org>";
|
lowfatcomputing = "Andreas Wagner <andreas.wagner@lowfatcomputing.org>";
|
||||||
lsix = "Lancelot SIX <lsix@lancelotsix.com>";
|
lsix = "Lancelot SIX <lsix@lancelotsix.com>";
|
||||||
|
ltavard = "Laure Tavard <laure.tavard@univ-grenoble-alpes.fr>";
|
||||||
lucas8 = "Luc Chabassier <luc.linux@mailoo.org>";
|
lucas8 = "Luc Chabassier <luc.linux@mailoo.org>";
|
||||||
ludo = "Ludovic Courtès <ludo@gnu.org>";
|
ludo = "Ludovic Courtès <ludo@gnu.org>";
|
||||||
|
lufia = "Kyohei Kadota <lufia@lufia.org>";
|
||||||
luispedro = "Luis Pedro Coelho <luis@luispedro.org>";
|
luispedro = "Luis Pedro Coelho <luis@luispedro.org>";
|
||||||
lukego = "Luke Gorrie <luke@snabb.co>";
|
lukego = "Luke Gorrie <luke@snabb.co>";
|
||||||
lw = "Sergey Sofeychuk <lw@fmap.me>";
|
lw = "Sergey Sofeychuk <lw@fmap.me>";
|
||||||
|
lyt = "Tim Liou <wheatdoge@gmail.com>";
|
||||||
|
m3tti = "Mathaeus Sander <mathaeus.peter.sander@gmail.com>";
|
||||||
ma27 = "Maximilian Bosch <maximilian@mbosch.me>";
|
ma27 = "Maximilian Bosch <maximilian@mbosch.me>";
|
||||||
madjar = "Georges Dubus <georges.dubus@compiletoi.net>";
|
madjar = "Georges Dubus <georges.dubus@compiletoi.net>";
|
||||||
magnetophon = "Bart Brouns <bart@magnetophon.nl>";
|
magnetophon = "Bart Brouns <bart@magnetophon.nl>";
|
||||||
@@ -318,17 +391,19 @@
|
|||||||
mcmtroffaes = "Matthias C. M. Troffaes <matthias.troffaes@gmail.com>";
|
mcmtroffaes = "Matthias C. M. Troffaes <matthias.troffaes@gmail.com>";
|
||||||
mdaiter = "Matthew S. Daiter <mdaiter8121@gmail.com>";
|
mdaiter = "Matthew S. Daiter <mdaiter8121@gmail.com>";
|
||||||
meditans = "Carlo Nucera <meditans@gmail.com>";
|
meditans = "Carlo Nucera <meditans@gmail.com>";
|
||||||
|
mehandes = "Matt Deming <niewskici@gmail.com>";
|
||||||
meisternu = "Matt Miemiec <meister@krutt.org>";
|
meisternu = "Matt Miemiec <meister@krutt.org>";
|
||||||
metabar = "Celine Mercier <softs@metabarcoding.org>";
|
metabar = "Celine Mercier <softs@metabarcoding.org>";
|
||||||
|
mgdelacroix = "Miguel de la Cruz <mgdelacroix@gmail.com>";
|
||||||
mguentner = "Maximilian Güntner <code@klandest.in>";
|
mguentner = "Maximilian Güntner <code@klandest.in>";
|
||||||
mic92 = "Jörg Thalheim <joerg@thalheim.io>";
|
mic92 = "Jörg Thalheim <joerg@thalheim.io>";
|
||||||
michaelpj = "Michael Peyton Jones <michaelpj@gmail.com>";
|
michaelpj = "Michael Peyton Jones <michaelpj@gmail.com>";
|
||||||
michalrus = "Michal Rus <m@michalrus.com>";
|
michalrus = "Michal Rus <m@michalrus.com>";
|
||||||
michelk = "Michel Kuhlmann <michel@kuhlmanns.info>";
|
michelk = "Michel Kuhlmann <michel@kuhlmanns.info>";
|
||||||
|
midchildan = "midchildan <midchildan+nix@gmail.com>";
|
||||||
mikefaille = "Michaël Faille <michael@faille.io>";
|
mikefaille = "Michaël Faille <michael@faille.io>";
|
||||||
miltador = "Vasiliy Solovey <miltador@yandex.ua>";
|
miltador = "Vasiliy Solovey <miltador@yandex.ua>";
|
||||||
mimadrid = "Miguel Madrid <mimadrid@ucm.es>";
|
mimadrid = "Miguel Madrid <mimadrid@ucm.es>";
|
||||||
mingchuan = "Ming Chuan <ming@culpring.com>";
|
|
||||||
mirdhyn = "Merlin Gaillard <mirdhyn@gmail.com>";
|
mirdhyn = "Merlin Gaillard <mirdhyn@gmail.com>";
|
||||||
mirrexagon = "Andrew Abbott <mirrexagon@mirrexagon.com>";
|
mirrexagon = "Andrew Abbott <mirrexagon@mirrexagon.com>";
|
||||||
mjanczyk = "Marcin Janczyk <m@dragonvr.pl>";
|
mjanczyk = "Marcin Janczyk <m@dragonvr.pl>";
|
||||||
@@ -342,11 +417,13 @@
|
|||||||
MostAwesomeDude = "Corbin Simpson <cds@corbinsimpson.com>";
|
MostAwesomeDude = "Corbin Simpson <cds@corbinsimpson.com>";
|
||||||
mounium = "Katona László <muoniurn@gmail.com>";
|
mounium = "Katona László <muoniurn@gmail.com>";
|
||||||
MP2E = "Cray Elliott <MP2E@archlinux.us>";
|
MP2E = "Cray Elliott <MP2E@archlinux.us>";
|
||||||
|
mpcsh = "Mark Cohen <m@mpc.sh>";
|
||||||
mpscholten = "Marc Scholten <marc@mpscholten.de>";
|
mpscholten = "Marc Scholten <marc@mpscholten.de>";
|
||||||
mpsyco = "Francis St-Amour <fr.st-amour@gmail.com>";
|
mpsyco = "Francis St-Amour <fr.st-amour@gmail.com>";
|
||||||
msackman = "Matthew Sackman <matthew@wellquite.org>";
|
msackman = "Matthew Sackman <matthew@wellquite.org>";
|
||||||
mschristiansen = "Mikkel Christiansen <mikkel@rheosystems.com>";
|
mschristiansen = "Mikkel Christiansen <mikkel@rheosystems.com>";
|
||||||
msteen = "Matthijs Steen <emailmatthijs@gmail.com>";
|
msteen = "Matthijs Steen <emailmatthijs@gmail.com>";
|
||||||
|
mt-caret = "Masayuki Takeda <mtakeda.enigsol@gmail.com>";
|
||||||
mtreskin = "Max Treskin <zerthurd@gmail.com>";
|
mtreskin = "Max Treskin <zerthurd@gmail.com>";
|
||||||
mudri = "James Wood <lamudri@gmail.com>";
|
mudri = "James Wood <lamudri@gmail.com>";
|
||||||
muflax = "Stefan Dorn <mail@muflax.com>";
|
muflax = "Stefan Dorn <mail@muflax.com>";
|
||||||
@@ -355,22 +432,24 @@
|
|||||||
nand0p = "Fernando Jose Pando <nando@hex7.com>";
|
nand0p = "Fernando Jose Pando <nando@hex7.com>";
|
||||||
Nate-Devv = "Nathan Moore <natedevv@gmail.com>";
|
Nate-Devv = "Nathan Moore <natedevv@gmail.com>";
|
||||||
nathan-gs = "Nathan Bijnens <nathan@nathan.gs>";
|
nathan-gs = "Nathan Bijnens <nathan@nathan.gs>";
|
||||||
nckx = "Tobias Geerinckx-Rice <tobias.geerinckx.rice@gmail.com>";
|
nckx = "Tobias Geerinckx-Rice <github@tobias.gr>";
|
||||||
ndowens = "Nathan Owens <ndowens04@gmail.com>";
|
ndowens = "Nathan Owens <ndowens04@gmail.com>";
|
||||||
neeasade = "Nathan Isom <nathanisom27@gmail.com>";
|
neeasade = "Nathan Isom <nathanisom27@gmail.com>";
|
||||||
nequissimus = "Tim Steinbach <tim@nequissimus.com>";
|
nequissimus = "Tim Steinbach <tim@nequissimus.com>";
|
||||||
nfjinjing = "Jinjing Wang <nfjinjing@gmail.com>";
|
nfjinjing = "Jinjing Wang <nfjinjing@gmail.com>";
|
||||||
|
nh2 = "Niklas Hambüchen <mail@nh2.me>";
|
||||||
nhooyr = "Anmol Sethi <anmol@aubble.com>";
|
nhooyr = "Anmol Sethi <anmol@aubble.com>";
|
||||||
nickhu = "Nick Hu <me@nickhu.co.uk>";
|
nickhu = "Nick Hu <me@nickhu.co.uk>";
|
||||||
nicknovitski = "Nick Novitski <nixpkgs@nicknovitski.com>";
|
nicknovitski = "Nick Novitski <nixpkgs@nicknovitski.com>";
|
||||||
nico202 = "Nicolò Balzarotti <anothersms@gmail.com>";
|
nico202 = "Nicolò Balzarotti <anothersms@gmail.com>";
|
||||||
NikolaMandic = "Ratko Mladic <nikola@mandic.email>";
|
NikolaMandic = "Ratko Mladic <nikola@mandic.email>";
|
||||||
nixy = "Andrew R. M. <andrewmiller237@gmail.com>";
|
nixy = "Andrew R. M. <nixy@nixy.moe>";
|
||||||
nocoolnametom = "Tom Doggett <nocoolnametom@gmail.com>";
|
nocoolnametom = "Tom Doggett <nocoolnametom@gmail.com>";
|
||||||
notthemessiah = "Brian Cohen <brian.cohen.88@gmail.com>";
|
notthemessiah = "Brian Cohen <brian.cohen.88@gmail.com>";
|
||||||
np = "Nicolas Pouillard <np.nix@nicolaspouillard.fr>";
|
np = "Nicolas Pouillard <np.nix@nicolaspouillard.fr>";
|
||||||
nslqqq = "Nikita Mikhailov <nslqqq@gmail.com>";
|
nslqqq = "Nikita Mikhailov <nslqqq@gmail.com>";
|
||||||
nthorne = "Niklas Thörne <notrupertthorne@gmail.com>";
|
nthorne = "Niklas Thörne <notrupertthorne@gmail.com>";
|
||||||
|
nyarly = "Judson Lester <nyarly@gmail.com>";
|
||||||
obadz = "obadz <obadz-nixos@obadz.com>";
|
obadz = "obadz <obadz-nixos@obadz.com>";
|
||||||
ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
|
ocharles = "Oliver Charles <ollie@ocharles.org.uk>";
|
||||||
odi = "Oliver Dunkl <oliver.dunkl@gmail.com>";
|
odi = "Oliver Dunkl <oliver.dunkl@gmail.com>";
|
||||||
@@ -379,6 +458,7 @@
|
|||||||
okasu = "Okasu <oka.sux@gmail.com>";
|
okasu = "Okasu <oka.sux@gmail.com>";
|
||||||
olcai = "Erik Timan <dev@timan.info>";
|
olcai = "Erik Timan <dev@timan.info>";
|
||||||
olejorgenb = "Ole Jørgen Brønner <olejorgenb@yahoo.no>";
|
olejorgenb = "Ole Jørgen Brønner <olejorgenb@yahoo.no>";
|
||||||
|
olynch = "Owen Lynch <owen@olynch.me>";
|
||||||
orbekk = "KJ Ørbekk <kjetil.orbekk@gmail.com>";
|
orbekk = "KJ Ørbekk <kjetil.orbekk@gmail.com>";
|
||||||
orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
|
orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
|
||||||
orivej = "Orivej Desh <orivej@gmx.fr>";
|
orivej = "Orivej Desh <orivej@gmx.fr>";
|
||||||
@@ -388,6 +468,7 @@
|
|||||||
paholg = "Paho Lurie-Gregg <paho@paholg.com>";
|
paholg = "Paho Lurie-Gregg <paho@paholg.com>";
|
||||||
pakhfn = "Fedor Pakhomov <pakhfn@gmail.com>";
|
pakhfn = "Fedor Pakhomov <pakhfn@gmail.com>";
|
||||||
palo = "Ingolf Wanger <palipalo9@googlemail.com>";
|
palo = "Ingolf Wanger <palipalo9@googlemail.com>";
|
||||||
|
panaeon = "Vitalii Voloshyn <vitalii.voloshyn@gmail.com";
|
||||||
paperdigits = "Mica Semrick <mica@silentumbrella.com>";
|
paperdigits = "Mica Semrick <mica@silentumbrella.com>";
|
||||||
pashev = "Igor Pashev <pashev.igor@gmail.com>";
|
pashev = "Igor Pashev <pashev.igor@gmail.com>";
|
||||||
patternspandemic = "Brad Christensen <patternspandemic@live.com>";
|
patternspandemic = "Brad Christensen <patternspandemic@live.com>";
|
||||||
@@ -396,6 +477,7 @@
|
|||||||
periklis = "theopompos@gmail.com";
|
periklis = "theopompos@gmail.com";
|
||||||
pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>";
|
pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>";
|
||||||
peterhoeg = "Peter Hoeg <peter@hoeg.com>";
|
peterhoeg = "Peter Hoeg <peter@hoeg.com>";
|
||||||
|
peterromfeldhk = "Peter Romfeld <peter.romfeld.hk@gmail.com>";
|
||||||
peti = "Peter Simons <simons@cryp.to>";
|
peti = "Peter Simons <simons@cryp.to>";
|
||||||
philandstuff = "Philip Potter <philip.g.potter@gmail.com>";
|
philandstuff = "Philip Potter <philip.g.potter@gmail.com>";
|
||||||
phile314 = "Philipp Hausmann <nix@314.ch>";
|
phile314 = "Philipp Hausmann <nix@314.ch>";
|
||||||
@@ -439,37 +521,47 @@
|
|||||||
relrod = "Ricky Elrod <ricky@elrod.me>";
|
relrod = "Ricky Elrod <ricky@elrod.me>";
|
||||||
renzo = "Renzo Carbonara <renzocarbonara@gmail.com>";
|
renzo = "Renzo Carbonara <renzocarbonara@gmail.com>";
|
||||||
retrry = "Tadas Barzdžius <retrry@gmail.com>";
|
retrry = "Tadas Barzdžius <retrry@gmail.com>";
|
||||||
|
rht = "rht <rhtbot@protonmail.com>";
|
||||||
|
richardipsum = "Richard Ipsum <richardipsum@fastmail.co.uk>";
|
||||||
rick68 = "Wei-Ming Yang <rick68@gmail.com>";
|
rick68 = "Wei-Ming Yang <rick68@gmail.com>";
|
||||||
rickynils = "Rickard Nilsson <rickynils@gmail.com>";
|
rickynils = "Rickard Nilsson <rickynils@gmail.com>";
|
||||||
|
ris = "Robert Scott <code@humanleg.org.uk>";
|
||||||
rlupton20 = "Richard Lupton <richard.lupton@gmail.com>";
|
rlupton20 = "Richard Lupton <richard.lupton@gmail.com>";
|
||||||
rnhmjoj = "Michele Guerini Rocco <micheleguerinirocco@me.com>";
|
rnhmjoj = "Michele Guerini Rocco <micheleguerinirocco@me.com>";
|
||||||
rob = "Rob Vermaas <rob.vermaas@gmail.com>";
|
rob = "Rob Vermaas <rob.vermaas@gmail.com>";
|
||||||
robberer = "Longrin Wischnewski <robberer@freakmail.de>";
|
robberer = "Longrin Wischnewski <robberer@freakmail.de>";
|
||||||
robbinch = "Robbin C. <robbinch33@gmail.com>";
|
robbinch = "Robbin C. <robbinch33@gmail.com>";
|
||||||
|
roberth = "Robert Hensing <nixpkgs@roberthensing.nl>";
|
||||||
|
robertodr = "Roberto Di Remigio <roberto.diremigio@gmail.com>";
|
||||||
robgssp = "Rob Glossop <robgssp@gmail.com>";
|
robgssp = "Rob Glossop <robgssp@gmail.com>";
|
||||||
roblabla = "Robin Lambertz <robinlambertz+dev@gmail.com>";
|
roblabla = "Robin Lambertz <robinlambertz+dev@gmail.com>";
|
||||||
roconnor = "Russell O'Connor <roconnor@theorem.ca>";
|
roconnor = "Russell O'Connor <roconnor@theorem.ca>";
|
||||||
romildo = "José Romildo Malaquias <malaquias@gmail.com>";
|
romildo = "José Romildo Malaquias <malaquias@gmail.com>";
|
||||||
rongcuid = "Rongcui Dong <rongcuid@outlook.com>";
|
rongcuid = "Rongcui Dong <rongcuid@outlook.com>";
|
||||||
ronny = "Ronny Pfannschmidt <nixos@ronnypfannschmidt.de>";
|
|
||||||
rszibele = "Richard Szibele <richard@szibele.com>";
|
rszibele = "Richard Szibele <richard@szibele.com>";
|
||||||
rtreffer = "Rene Treffer <treffer+nixos@measite.de>";
|
rtreffer = "Rene Treffer <treffer+nixos@measite.de>";
|
||||||
rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>";
|
rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>";
|
||||||
rvl = "Rodney Lorrimar <dev+nix@rodney.id.au>";
|
rvl = "Rodney Lorrimar <dev+nix@rodney.id.au>";
|
||||||
rvlander = "Gaëtan André <rvlander@gaetanandre.eu>";
|
rvlander = "Gaëtan André <rvlander@gaetanandre.eu>";
|
||||||
|
rvolosatovs = "Roman Volosatovs <rvolosatovs@riseup.net";
|
||||||
ryanartecona = "Ryan Artecona <ryanartecona@gmail.com>";
|
ryanartecona = "Ryan Artecona <ryanartecona@gmail.com>";
|
||||||
ryansydnor = "Ryan Sydnor <ryan.t.sydnor@gmail.com>";
|
ryansydnor = "Ryan Sydnor <ryan.t.sydnor@gmail.com>";
|
||||||
ryantm = "Ryan Mulligan <ryan@ryantm.com>";
|
ryantm = "Ryan Mulligan <ryan@ryantm.com>";
|
||||||
|
rybern = "Ryan Bernstein <ryan.bernstein@columbia.edu>";
|
||||||
rycee = "Robert Helgesson <robert@rycee.net>";
|
rycee = "Robert Helgesson <robert@rycee.net>";
|
||||||
ryneeverett = "Ryne Everett <ryneeverett@gmail.com>";
|
ryneeverett = "Ryne Everett <ryneeverett@gmail.com>";
|
||||||
rzetterberg = "Richard Zetterberg <richard.zetterberg@gmail.com>";
|
rzetterberg = "Richard Zetterberg <richard.zetterberg@gmail.com>";
|
||||||
s1lvester = "Markus Silvester <s1lvester@bockhacker.me>";
|
s1lvester = "Markus Silvester <s1lvester@bockhacker.me>";
|
||||||
|
samdroid-apps = "Sam Parkinson <sam@sam.today>";
|
||||||
samuelrivas = "Samuel Rivas <samuelrivas@gmail.com>";
|
samuelrivas = "Samuel Rivas <samuelrivas@gmail.com>";
|
||||||
sander = "Sander van der Burg <s.vanderburg@tudelft.nl>";
|
sander = "Sander van der Burg <s.vanderburg@tudelft.nl>";
|
||||||
|
sargon = "Daniel Ehlers <danielehlers@mindeye.net>";
|
||||||
|
sauyon = "Sauyon Lee <s@uyon.co>";
|
||||||
schmitthenner = "Fabian Schmitthenner <development@schmitthenner.eu>";
|
schmitthenner = "Fabian Schmitthenner <development@schmitthenner.eu>";
|
||||||
schneefux = "schneefux <schneefux+nixos_pkg@schneefux.xyz>";
|
schneefux = "schneefux <schneefux+nixos_pkg@schneefux.xyz>";
|
||||||
schristo = "Scott Christopher <schristopher@konputa.com>";
|
schristo = "Scott Christopher <schristopher@konputa.com>";
|
||||||
scolobb = "Sergiu Ivanov <sivanov@colimite.fr>";
|
scolobb = "Sergiu Ivanov <sivanov@colimite.fr>";
|
||||||
|
sdll = "Sasha Illarionov <sasha.delly@gmail.com>";
|
||||||
sepi = "Raffael Mancini <raffael@mancini.lu>";
|
sepi = "Raffael Mancini <raffael@mancini.lu>";
|
||||||
seppeljordan = "Sebastian Jordan <sebastian.jordan.mail@googlemail.com>";
|
seppeljordan = "Sebastian Jordan <sebastian.jordan.mail@googlemail.com>";
|
||||||
shanemikel = "Shane Pearlman <shanemikel1@gmail.com>";
|
shanemikel = "Shane Pearlman <shanemikel1@gmail.com>";
|
||||||
@@ -479,8 +571,10 @@
|
|||||||
shell = "Shell Turner <cam.turn@gmail.com>";
|
shell = "Shell Turner <cam.turn@gmail.com>";
|
||||||
shlevy = "Shea Levy <shea@shealevy.com>";
|
shlevy = "Shea Levy <shea@shealevy.com>";
|
||||||
siddharthist = "Langston Barrett <langston.barrett@gmail.com>";
|
siddharthist = "Langston Barrett <langston.barrett@gmail.com>";
|
||||||
|
sifmelcara = "Ming Chuan <ming@culpring.com>";
|
||||||
sigma = "Yann Hodique <yann.hodique@gmail.com>";
|
sigma = "Yann Hodique <yann.hodique@gmail.com>";
|
||||||
simonvandel = "Simon Vandel Sillesen <simon.vandel@gmail.com>";
|
simonvandel = "Simon Vandel Sillesen <simon.vandel@gmail.com>";
|
||||||
|
sivteck = "Sivaram Balakrishnan <sivaram1992@gmail.com>";
|
||||||
sjagoe = "Simon Jagoe <simon@simonjagoe.com>";
|
sjagoe = "Simon Jagoe <simon@simonjagoe.com>";
|
||||||
sjmackenzie = "Stewart Mackenzie <setori88@gmail.com>";
|
sjmackenzie = "Stewart Mackenzie <setori88@gmail.com>";
|
||||||
sjourdois = "Stéphane ‘kwisatz’ Jourdois <sjourdois@gmail.com>";
|
sjourdois = "Stéphane ‘kwisatz’ Jourdois <sjourdois@gmail.com>";
|
||||||
@@ -488,7 +582,10 @@
|
|||||||
skrzyp = "Jakub Skrzypnik <jot.skrzyp@gmail.com>";
|
skrzyp = "Jakub Skrzypnik <jot.skrzyp@gmail.com>";
|
||||||
sleexyz = "Sean Lee <freshdried@gmail.com>";
|
sleexyz = "Sean Lee <freshdried@gmail.com>";
|
||||||
smironov = "Sergey Mironov <grrwlf@gmail.com>";
|
smironov = "Sergey Mironov <grrwlf@gmail.com>";
|
||||||
|
snyh = "Xia Bin <snyh@snyh.org>";
|
||||||
solson = "Scott Olson <scott@solson.me>";
|
solson = "Scott Olson <scott@solson.me>";
|
||||||
|
sorpaas = "Wei Tang <hi@that.world>";
|
||||||
|
sorki = "Richard Marko <srk@48.io>";
|
||||||
spacefrogg = "Michael Raitza <spacefrogg-nixos@meterriblecrew.net>";
|
spacefrogg = "Michael Raitza <spacefrogg-nixos@meterriblecrew.net>";
|
||||||
spencerjanssen = "Spencer Janssen <spencerjanssen@gmail.com>";
|
spencerjanssen = "Spencer Janssen <spencerjanssen@gmail.com>";
|
||||||
spinus = "Tomasz Czyż <tomasz.czyz@gmail.com>";
|
spinus = "Tomasz Czyż <tomasz.czyz@gmail.com>";
|
||||||
@@ -500,8 +597,12 @@
|
|||||||
sternenseemann = "Lukas Epple <post@lukasepple.de>";
|
sternenseemann = "Lukas Epple <post@lukasepple.de>";
|
||||||
stesie = "Stefan Siegl <stesie@brokenpipe.de>";
|
stesie = "Stefan Siegl <stesie@brokenpipe.de>";
|
||||||
steveej = "Stefan Junker <mail@stefanjunker.de>";
|
steveej = "Stefan Junker <mail@stefanjunker.de>";
|
||||||
|
stumoss = "Stuart Moss <samoss@gmail.com>";
|
||||||
|
SuprDewd = "Bjarki Ágúst Guðmundsson <suprdewd@gmail.com>";
|
||||||
swarren83 = "Shawn Warren <shawn.w.warren@gmail.com>";
|
swarren83 = "Shawn Warren <shawn.w.warren@gmail.com>";
|
||||||
|
swflint = "Samuel W. Flint <swflint@flintfam.org>";
|
||||||
swistak35 = "Rafał Łasocha <me@swistak35.com>";
|
swistak35 = "Rafał Łasocha <me@swistak35.com>";
|
||||||
|
symphorien = "Guillaume Girol <symphorien_nixpkgs@xlumurb.eu>";
|
||||||
szczyp = "Szczyp <qb@szczyp.com>";
|
szczyp = "Szczyp <qb@szczyp.com>";
|
||||||
sztupi = "Attila Sztupak <attila.sztupak@gmail.com>";
|
sztupi = "Attila Sztupak <attila.sztupak@gmail.com>";
|
||||||
taeer = "Taeer Bar-Yam <taeer@necsi.edu>";
|
taeer = "Taeer Bar-Yam <taeer@necsi.edu>";
|
||||||
@@ -509,32 +610,44 @@
|
|||||||
takikawa = "Asumu Takikawa <asumu@igalia.com>";
|
takikawa = "Asumu Takikawa <asumu@igalia.com>";
|
||||||
taktoa = "Remy Goldschmidt <taktoa@gmail.com>";
|
taktoa = "Remy Goldschmidt <taktoa@gmail.com>";
|
||||||
taku0 = "Takuo Yonezawa <mxxouy6x3m_github@tatapa.org>";
|
taku0 = "Takuo Yonezawa <mxxouy6x3m_github@tatapa.org>";
|
||||||
|
tari = "Peter Marheine <peter@taricorp.net>";
|
||||||
tavyc = "Octavian Cerna <octavian.cerna@gmail.com>";
|
tavyc = "Octavian Cerna <octavian.cerna@gmail.com>";
|
||||||
|
TealG = "Teal Gaure <~@Teal.Gr>";
|
||||||
teh = "Tom Hunger <tehunger@gmail.com>";
|
teh = "Tom Hunger <tehunger@gmail.com>";
|
||||||
telotortium = "Robert Irelan <rirelan@gmail.com>";
|
telotortium = "Robert Irelan <rirelan@gmail.com>";
|
||||||
|
teto = "Matthieu Coudron <mcoudron@hotmail.com>";
|
||||||
|
tex = "Milan Svoboda <milan.svoboda@centrum.cz>";
|
||||||
thall = "Niclas Thall <niclas.thall@gmail.com>";
|
thall = "Niclas Thall <niclas.thall@gmail.com>";
|
||||||
thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
|
thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
|
||||||
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
|
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
|
||||||
theuni = "Christian Theune <ct@flyingcircus.io>";
|
theuni = "Christian Theune <ct@flyingcircus.io>";
|
||||||
|
ThomasMader = "Thomas Mader <thomas.mader@gmail.com>";
|
||||||
thoughtpolice = "Austin Seipp <aseipp@pobox.com>";
|
thoughtpolice = "Austin Seipp <aseipp@pobox.com>";
|
||||||
timbertson = "Tim Cuthbertson <tim@gfxmonk.net>";
|
timbertson = "Tim Cuthbertson <tim@gfxmonk.net>";
|
||||||
titanous = "Jonathan Rudenberg <jonathan@titanous.com>";
|
titanous = "Jonathan Rudenberg <jonathan@titanous.com>";
|
||||||
|
tnias = "Philipp Bartsch <phil@grmr.de>";
|
||||||
tohl = "Tomas Hlavaty <tom@logand.com>";
|
tohl = "Tomas Hlavaty <tom@logand.com>";
|
||||||
tokudan = "Daniel Frank <git@danielfrank.net>";
|
tokudan = "Daniel Frank <git@danielfrank.net>";
|
||||||
tomberek = "Thomas Bereknyei <tomberek@gmail.com>";
|
tomberek = "Thomas Bereknyei <tomberek@gmail.com>";
|
||||||
|
tomsmeets = "Tom Smeets <tom@tsmeets.nl>";
|
||||||
travisbhartwell = "Travis B. Hartwell <nafai@travishartwell.net>";
|
travisbhartwell = "Travis B. Hartwell <nafai@travishartwell.net>";
|
||||||
|
trevorj = "Trevor Joynson <nix@trevor.joynson.io>";
|
||||||
trino = "Hubert Mühlhans <muehlhans.hubert@ekodia.de>";
|
trino = "Hubert Mühlhans <muehlhans.hubert@ekodia.de>";
|
||||||
tstrobel = "Thomas Strobel <4ZKTUB6TEP74PYJOPWIR013S2AV29YUBW5F9ZH2F4D5UMJUJ6S@hash.domains>";
|
tstrobel = "Thomas Strobel <4ZKTUB6TEP74PYJOPWIR013S2AV29YUBW5F9ZH2F4D5UMJUJ6S@hash.domains>";
|
||||||
ttuegel = "Thomas Tuegel <ttuegel@mailbox.org>";
|
ttuegel = "Thomas Tuegel <ttuegel@mailbox.org>";
|
||||||
tv = "Tomislav Viljetić <tv@shackspace.de>";
|
tv = "Tomislav Viljetić <tv@shackspace.de>";
|
||||||
tvestelind = "Tomas Vestelind <tomas.vestelind@fripost.org>";
|
tvestelind = "Tomas Vestelind <tomas.vestelind@fripost.org>";
|
||||||
tvorog = "Marsel Zaripov <marszaripov@gmail.com>";
|
tvorog = "Marsel Zaripov <marszaripov@gmail.com>";
|
||||||
|
tweber = "Thorsten Weber <tw+nixpkgs@360vier.de>";
|
||||||
twey = "James ‘Twey’ Kay <twey@twey.co.uk>";
|
twey = "James ‘Twey’ Kay <twey@twey.co.uk>";
|
||||||
uralbash = "Svintsov Dmitry <root@uralbash.ru>";
|
uralbash = "Svintsov Dmitry <root@uralbash.ru>";
|
||||||
utdemir = "Utku Demir <me@utdemir.com>";
|
utdemir = "Utku Demir <me@utdemir.com>";
|
||||||
#urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>"; inactive since 2012
|
#urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>"; inactive since 2012
|
||||||
uwap = "uwap <me@uwap.name>";
|
uwap = "uwap <me@uwap.name>";
|
||||||
|
vaibhavsagar = "Vaibhav Sagar <vaibhavsagar@gmail.com>";
|
||||||
|
valeriangalliat = "Valérian Galliat <val@codejam.info>";
|
||||||
vandenoever = "Jos van den Oever <jos@vandenoever.info>";
|
vandenoever = "Jos van den Oever <jos@vandenoever.info>";
|
||||||
|
vanschelven = "Klaas van Schelven <klaas@vanschelven.com>";
|
||||||
vanzef = "Ivan Solyankin <vanzef@gmail.com>";
|
vanzef = "Ivan Solyankin <vanzef@gmail.com>";
|
||||||
vbgl = "Vincent Laporte <Vincent.Laporte@gmail.com>";
|
vbgl = "Vincent Laporte <Vincent.Laporte@gmail.com>";
|
||||||
vbmithr = "Vincent Bernardoff <vb@luminar.eu.org>";
|
vbmithr = "Vincent Bernardoff <vb@luminar.eu.org>";
|
||||||
@@ -542,38 +655,52 @@
|
|||||||
vdemeester = "Vincent Demeester <vincent@sbr.pm>";
|
vdemeester = "Vincent Demeester <vincent@sbr.pm>";
|
||||||
veprbl = "Dmitry Kalinkin <veprbl@gmail.com>";
|
veprbl = "Dmitry Kalinkin <veprbl@gmail.com>";
|
||||||
vifino = "Adrian Pistol <vifino@tty.sh>";
|
vifino = "Adrian Pistol <vifino@tty.sh>";
|
||||||
|
vinymeuh = "VinyMeuh <vinymeuh@gmail.com>";
|
||||||
viric = "Lluís Batlle i Rossell <viric@viric.name>";
|
viric = "Lluís Batlle i Rossell <viric@viric.name>";
|
||||||
vizanto = "Danny Wilson <danny@prime.vc>";
|
vizanto = "Danny Wilson <danny@prime.vc>";
|
||||||
vklquevs = "vklquevs <vklquevs@gmail.com>";
|
vklquevs = "vklquevs <vklquevs@gmail.com>";
|
||||||
vlstill = "Vladimír Štill <xstill@fi.muni.cz>";
|
vlstill = "Vladimír Štill <xstill@fi.muni.cz>";
|
||||||
vmandela = "Venkateswara Rao Mandela <venkat.mandela@gmail.com>";
|
vmandela = "Venkateswara Rao Mandela <venkat.mandela@gmail.com>";
|
||||||
|
vmchale = "Vanessa McHale <tmchale@wisc.edu>";
|
||||||
volhovm = "Mikhail Volkhov <volhovm.cs@gmail.com>";
|
volhovm = "Mikhail Volkhov <volhovm.cs@gmail.com>";
|
||||||
volth = "Jaroslavas Pocepko <jaroslavas@volth.com>";
|
volth = "Jaroslavas Pocepko <jaroslavas@volth.com>";
|
||||||
vozz = "Oliver Hunt <oliver.huntuk@gmail.com>";
|
vozz = "Oliver Hunt <oliver.huntuk@gmail.com>";
|
||||||
vrthra = "Rahul Gopinath <rahul@gopinath.org>";
|
vrthra = "Rahul Gopinath <rahul@gopinath.org>";
|
||||||
|
vyp = "vyp <elisp.vim@gmail.com>";
|
||||||
wedens = "wedens <kirill.wedens@gmail.com>";
|
wedens = "wedens <kirill.wedens@gmail.com>";
|
||||||
|
willibutz = "Willi Butz <willibutz@posteo.de>";
|
||||||
willtim = "Tim Philip Williams <tim.williams.public@gmail.com>";
|
willtim = "Tim Philip Williams <tim.williams.public@gmail.com>";
|
||||||
winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>";
|
winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>";
|
||||||
wizeman = "Ricardo M. Correia <rcorreia@wizy.org>";
|
wizeman = "Ricardo M. Correia <rcorreia@wizy.org>";
|
||||||
wjlroe = "William Roe <willroe@gmail.com>";
|
wjlroe = "William Roe <willroe@gmail.com>";
|
||||||
wkennington = "William A. Kennington III <william@wkennington.com>";
|
wkennington = "William A. Kennington III <william@wkennington.com>";
|
||||||
wmertens = "Wout Mertens <Wout.Mertens@gmail.com>";
|
wmertens = "Wout Mertens <Wout.Mertens@gmail.com>";
|
||||||
|
woffs = "Frank Doepper <github@woffs.de>";
|
||||||
womfoo = "Kranium Gikos Mendoza <kranium@gikos.net>";
|
womfoo = "Kranium Gikos Mendoza <kranium@gikos.net>";
|
||||||
wscott = "Wayne Scott <wsc9tt@gmail.com>";
|
wscott = "Wayne Scott <wsc9tt@gmail.com>";
|
||||||
wyvie = "Elijah Rum <elijahrum@gmail.com>";
|
wyvie = "Elijah Rum <elijahrum@gmail.com>";
|
||||||
xnwdd = "Guillermo NWDD <nwdd+nixos@no.team>";
|
xnwdd = "Guillermo NWDD <nwdd+nixos@no.team>";
|
||||||
xvapx = "Marti Serra <marti.serra.coscollano@gmail.com>";
|
xvapx = "Marti Serra <marti.serra.coscollano@gmail.com>";
|
||||||
xwvvvvwx = "David Terry <davidterry@posteo.de>";
|
xwvvvvwx = "David Terry <davidterry@posteo.de>";
|
||||||
|
xzfc = "Albert Safin <xzfcpw@gmail.com>";
|
||||||
yarr = "Dmitry V. <savraz@gmail.com>";
|
yarr = "Dmitry V. <savraz@gmail.com>";
|
||||||
|
yegortimoshenko = "Yegor Timoshenko <yegortimoshenko@gmail.com>";
|
||||||
|
ylwghst = "Burim Augustin Berisa <ylwghst@onionmail.info>";
|
||||||
yochai = "Yochai <yochai@titat.info>";
|
yochai = "Yochai <yochai@titat.info>";
|
||||||
yorickvp = "Yorick van Pelt <yorickvanpelt@gmail.com>";
|
yorickvp = "Yorick van Pelt <yorickvanpelt@gmail.com>";
|
||||||
|
yuriaisaka = "Yuri Aisaka <yuri.aisaka+nix@gmail.com>";
|
||||||
yurrriq = "Eric Bailey <eric@ericb.me>";
|
yurrriq = "Eric Bailey <eric@ericb.me>";
|
||||||
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
|
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
|
||||||
zagy = "Christian Zagrodnick <cz@flyingcircus.io>";
|
zagy = "Christian Zagrodnick <cz@flyingcircus.io>";
|
||||||
|
zalakain = "Unai Zalakain <contact@unaizalakain.info>";
|
||||||
|
zarelit = "David Costa <david@zarel.net>";
|
||||||
zauberpony = "Elmar Athmer <elmar@athmer.org>";
|
zauberpony = "Elmar Athmer <elmar@athmer.org>";
|
||||||
zef = "Zef Hemel <zef@zef.me>";
|
zef = "Zef Hemel <zef@zef.me>";
|
||||||
zimbatm = "zimbatm <zimbatm@zimbatm.com>";
|
zimbatm = "zimbatm <zimbatm@zimbatm.com>";
|
||||||
|
Zimmi48 = "Théo Zimmermann <theo.zimmermann@univ-paris-diderot.fr>";
|
||||||
zohl = "Al Zohali <zohl@fmap.me>";
|
zohl = "Al Zohali <zohl@fmap.me>";
|
||||||
zoomulator = "Kim Simmons <zoomulator@gmail.com>";
|
zoomulator = "Kim Simmons <zoomulator@gmail.com>";
|
||||||
zraexy = "David Mell <zraexy@gmail.com>";
|
zraexy = "David Mell <zraexy@gmail.com>";
|
||||||
|
zx2c4 = "Jason A. Donenfeld <Jason@zx2c4.com>";
|
||||||
|
zzamboni = "Diego Zamboni <diego@zzamboni.org>";
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-4
@@ -1,8 +1,7 @@
|
|||||||
/* Some functions for manipulating meta attributes, as well as the
|
/* Some functions for manipulating meta attributes, as well as the
|
||||||
name attribute. */
|
name attribute. */
|
||||||
|
|
||||||
let lib = import ./default.nix;
|
{ lib }:
|
||||||
in
|
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
@@ -17,6 +16,11 @@ rec {
|
|||||||
drv // { meta = (drv.meta or {}) // newAttrs; };
|
drv // { meta = (drv.meta or {}) // newAttrs; };
|
||||||
|
|
||||||
|
|
||||||
|
/* Disable Hydra builds of given derivation.
|
||||||
|
*/
|
||||||
|
dontDistribute = drv: addMetaAttrs { hydraPlatforms = []; } drv;
|
||||||
|
|
||||||
|
|
||||||
/* Change the symbolic name of a package for presentation purposes
|
/* Change the symbolic name of a package for presentation purposes
|
||||||
(i.e., so that nix-env users can tell them apart).
|
(i.e., so that nix-env users can tell them apart).
|
||||||
*/
|
*/
|
||||||
@@ -45,7 +49,7 @@ rec {
|
|||||||
/* Decrease the nix-env priority of the package, i.e., other
|
/* Decrease the nix-env priority of the package, i.e., other
|
||||||
versions/variants of the package will be preferred.
|
versions/variants of the package will be preferred.
|
||||||
*/
|
*/
|
||||||
lowPrio = drv: addMetaAttrs { priority = "10"; } drv;
|
lowPrio = drv: addMetaAttrs { priority = 10; } drv;
|
||||||
|
|
||||||
|
|
||||||
/* Apply lowPrio to an attrset with derivations
|
/* Apply lowPrio to an attrset with derivations
|
||||||
@@ -56,7 +60,7 @@ rec {
|
|||||||
/* Increase the nix-env priority of the package, i.e., this
|
/* Increase the nix-env priority of the package, i.e., this
|
||||||
version/variant of the package will be preferred.
|
version/variant of the package will be preferred.
|
||||||
*/
|
*/
|
||||||
hiPrio = drv: addMetaAttrs { priority = "-10"; } drv;
|
hiPrio = drv: addMetaAttrs { priority = -10; } drv;
|
||||||
|
|
||||||
|
|
||||||
/* Apply hiPrio to an attrset with derivations
|
/* Apply hiPrio to an attrset with derivations
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
# Expose the minimum required version for evaluating Nixpkgs
|
# Expose the minimum required version for evaluating Nixpkgs
|
||||||
"1.10"
|
"1.11"
|
||||||
|
|||||||
+10
-8
@@ -1,10 +1,12 @@
|
|||||||
with import ./lists.nix;
|
{ lib }:
|
||||||
with import ./strings.nix;
|
|
||||||
with import ./trivial.nix;
|
with lib.lists;
|
||||||
with import ./attrsets.nix;
|
with lib.strings;
|
||||||
with import ./options.nix;
|
with lib.trivial;
|
||||||
with import ./debug.nix;
|
with lib.attrsets;
|
||||||
with import ./types.nix;
|
with lib.options;
|
||||||
|
with lib.debug;
|
||||||
|
with lib.types;
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
@@ -98,7 +100,7 @@ rec {
|
|||||||
/* Close a set of modules under the ‘imports’ relation. */
|
/* Close a set of modules under the ‘imports’ relation. */
|
||||||
closeModules = modules: args:
|
closeModules = modules: args:
|
||||||
let
|
let
|
||||||
toClosureList = file: parentKey: imap (n: x:
|
toClosureList = file: parentKey: imap1 (n: x:
|
||||||
if isAttrs x || isFunction x then
|
if isAttrs x || isFunction x then
|
||||||
let key = "${parentKey}:anon-${toString n}"; in
|
let key = "${parentKey}:anon-${toString n}"; in
|
||||||
unifyModuleSyntax file key (unpackSubmodule (applyIfFunction key) x args)
|
unifyModuleSyntax file key (unpackSubmodule (applyIfFunction key) x args)
|
||||||
|
|||||||
+5
-6
@@ -1,11 +1,10 @@
|
|||||||
# Nixpkgs/NixOS option handling.
|
# Nixpkgs/NixOS option handling.
|
||||||
|
{ lib }:
|
||||||
|
|
||||||
let lib = import ./default.nix; in
|
with lib.trivial;
|
||||||
|
with lib.lists;
|
||||||
with import ./trivial.nix;
|
with lib.attrsets;
|
||||||
with import ./lists.nix;
|
with lib.strings;
|
||||||
with import ./attrsets.nix;
|
|
||||||
with import ./strings.nix;
|
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
with import ./strings.nix;
|
{ lib }:
|
||||||
|
with lib.strings;
|
||||||
|
|
||||||
/* Helpers for creating lisp S-exprs for the Apple sandbox
|
/* Helpers for creating lisp S-exprs for the Apple sandbox
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -1,6 +1,5 @@
|
|||||||
# Functions for copying sources to the Nix store.
|
# Functions for copying sources to the Nix store.
|
||||||
|
{ lib }:
|
||||||
let lib = import ./default.nix; in
|
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
@@ -15,8 +14,11 @@ rec {
|
|||||||
cleanSourceFilter = name: type: let baseName = baseNameOf (toString name); in ! (
|
cleanSourceFilter = name: type: let baseName = baseNameOf (toString name); in ! (
|
||||||
# Filter out Subversion and CVS directories.
|
# Filter out Subversion and CVS directories.
|
||||||
(type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
|
(type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
|
||||||
# Filter out backup files.
|
# Filter out editor backup / swap files.
|
||||||
lib.hasSuffix "~" baseName ||
|
lib.hasSuffix "~" baseName ||
|
||||||
|
builtins.match "^\\.sw[a-z]$" baseName != null ||
|
||||||
|
builtins.match "^\\..*\\.sw[a-z]$" baseName != null ||
|
||||||
|
|
||||||
# Filter out generates files.
|
# Filter out generates files.
|
||||||
lib.hasSuffix ".o" baseName ||
|
lib.hasSuffix ".o" baseName ||
|
||||||
lib.hasSuffix ".so" baseName ||
|
lib.hasSuffix ".so" baseName ||
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{ lib }:
|
||||||
/*
|
/*
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
@@ -40,9 +41,9 @@ Usage:
|
|||||||
[1] maybe this behaviour should be removed to keep things simple (?)
|
[1] maybe this behaviour should be removed to keep things simple (?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
with import ./lists.nix;
|
with lib.lists;
|
||||||
with import ./attrsets.nix;
|
with lib.attrsets;
|
||||||
with import ./strings.nix;
|
with lib.strings;
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
|
|||||||
+10
-5
@@ -1,6 +1,6 @@
|
|||||||
/* String manipulation functions. */
|
/* String manipulation functions. */
|
||||||
|
{ lib }:
|
||||||
let lib = import ./default.nix;
|
let
|
||||||
|
|
||||||
inherit (builtins) length;
|
inherit (builtins) length;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ rec {
|
|||||||
concatImapStrings (pos: x: "${toString pos}-${x}") ["foo" "bar"]
|
concatImapStrings (pos: x: "${toString pos}-${x}") ["foo" "bar"]
|
||||||
=> "1-foo2-bar"
|
=> "1-foo2-bar"
|
||||||
*/
|
*/
|
||||||
concatImapStrings = f: list: concatStrings (lib.imap f list);
|
concatImapStrings = f: list: concatStrings (lib.imap1 f list);
|
||||||
|
|
||||||
/* Place an element between each element of a list
|
/* Place an element between each element of a list
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ rec {
|
|||||||
concatImapStringsSep "-" (pos: x: toString (x / pos)) [ 6 6 6 ]
|
concatImapStringsSep "-" (pos: x: toString (x / pos)) [ 6 6 6 ]
|
||||||
=> "6-3-2"
|
=> "6-3-2"
|
||||||
*/
|
*/
|
||||||
concatImapStringsSep = sep: f: list: concatStringsSep sep (lib.imap f list);
|
concatImapStringsSep = sep: f: list: concatStringsSep sep (lib.imap1 f list);
|
||||||
|
|
||||||
/* Construct a Unix-style search path consisting of each `subDir"
|
/* Construct a Unix-style search path consisting of each `subDir"
|
||||||
directory of the given list of packages.
|
directory of the given list of packages.
|
||||||
@@ -438,8 +438,13 @@ rec {
|
|||||||
=> true
|
=> true
|
||||||
isStorePath pkgs.python
|
isStorePath pkgs.python
|
||||||
=> true
|
=> true
|
||||||
|
isStorePath [] || isStorePath 42 || isStorePath {} || …
|
||||||
|
=> false
|
||||||
*/
|
*/
|
||||||
isStorePath = x: builtins.substring 0 1 (toString x) == "/" && dirOf (builtins.toPath x) == builtins.storeDir;
|
isStorePath = x:
|
||||||
|
builtins.isString x
|
||||||
|
&& builtins.substring 0 1 (toString x) == "/"
|
||||||
|
&& dirOf (builtins.toPath x) == builtins.storeDir;
|
||||||
|
|
||||||
/* Convert string to int
|
/* Convert string to int
|
||||||
Obviously, it is a bit hacky to use fromJSON that way.
|
Obviously, it is a bit hacky to use fromJSON that way.
|
||||||
|
|||||||
+25
-4
@@ -1,7 +1,12 @@
|
|||||||
|
{ lib }:
|
||||||
|
let inherit (lib.attrsets) mapAttrs; in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
doubles = import ./doubles.nix;
|
doubles = import ./doubles.nix { inherit lib; };
|
||||||
parse = import ./parse.nix;
|
parse = import ./parse.nix { inherit lib; };
|
||||||
platforms = import ./platforms.nix;
|
inspect = import ./inspect.nix { inherit lib; };
|
||||||
|
platforms = import ./platforms.nix { inherit lib; };
|
||||||
|
examples = import ./examples.nix { inherit lib; };
|
||||||
|
|
||||||
# Elaborate a `localSystem` or `crossSystem` so that it contains everything
|
# Elaborate a `localSystem` or `crossSystem` so that it contains everything
|
||||||
# necessary.
|
# necessary.
|
||||||
@@ -18,6 +23,22 @@ rec {
|
|||||||
config = parse.tripleFromSystem final.parsed;
|
config = parse.tripleFromSystem final.parsed;
|
||||||
# Just a guess, based on `system`
|
# Just a guess, based on `system`
|
||||||
platform = platforms.selectBySystem final.system;
|
platform = platforms.selectBySystem final.system;
|
||||||
} // args;
|
libc =
|
||||||
|
/**/ if final.isDarwin then "libSystem"
|
||||||
|
else if final.isMinGW then "msvcrt"
|
||||||
|
else if final.isLinux then "glibc"
|
||||||
|
# TODO(@Ericson2314) think more about other operating systems
|
||||||
|
else "native/impure";
|
||||||
|
extensions = {
|
||||||
|
sharedLibrary =
|
||||||
|
/**/ if final.isDarwin then ".dylib"
|
||||||
|
else if final.isWindows then ".dll"
|
||||||
|
else ".so";
|
||||||
|
executable =
|
||||||
|
/**/ if final.isWindows then ".exe"
|
||||||
|
else "";
|
||||||
|
};
|
||||||
|
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
||||||
|
// args;
|
||||||
in final;
|
in final;
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-17
@@ -1,8 +1,10 @@
|
|||||||
let lists = import ../lists.nix; in
|
{ lib }:
|
||||||
let parse = import ./parse.nix; in
|
|
||||||
let inherit (import ../attrsets.nix) matchAttrs; in
|
|
||||||
|
|
||||||
let
|
let
|
||||||
|
inherit (lib) lists;
|
||||||
|
parse = import ./parse.nix { inherit lib; };
|
||||||
|
inherit (import ./inspect.nix { inherit lib; }) predicates;
|
||||||
|
inherit (lib.attrsets) matchAttrs;
|
||||||
|
|
||||||
all = [
|
all = [
|
||||||
"aarch64-linux"
|
"aarch64-linux"
|
||||||
"armv5tel-linux" "armv6l-linux" "armv7l-linux"
|
"armv5tel-linux" "armv6l-linux" "armv7l-linux"
|
||||||
@@ -25,20 +27,21 @@ in rec {
|
|||||||
allBut = platforms: lists.filter (x: !(builtins.elem x platforms)) all;
|
allBut = platforms: lists.filter (x: !(builtins.elem x platforms)) all;
|
||||||
none = [];
|
none = [];
|
||||||
|
|
||||||
arm = filterDoubles (matchAttrs { cpu = { family = "arm"; bits = 32; }; });
|
arm = filterDoubles predicates.isArm;
|
||||||
i686 = filterDoubles parse.isi686;
|
i686 = filterDoubles predicates.isi686;
|
||||||
mips = filterDoubles (matchAttrs { cpu = { family = "mips"; }; });
|
mips = filterDoubles predicates.isMips;
|
||||||
x86_64 = filterDoubles parse.isx86_64;
|
x86_64 = filterDoubles predicates.isx86_64;
|
||||||
|
|
||||||
cygwin = filterDoubles (matchAttrs { kernel = parse.kernels.cygwin; });
|
cygwin = filterDoubles predicates.isCygwin;
|
||||||
darwin = filterDoubles parse.isDarwin;
|
darwin = filterDoubles predicates.isDarwin;
|
||||||
freebsd = filterDoubles (matchAttrs { kernel = parse.kernels.freebsd; });
|
freebsd = filterDoubles predicates.isFreeBSD;
|
||||||
gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; }); # Should be better
|
# Should be better, but MinGW is unclear, and HURD is bit-rotted.
|
||||||
illumos = filterDoubles (matchAttrs { kernel = parse.kernels.solaris; });
|
gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; });
|
||||||
linux = filterDoubles parse.isLinux;
|
illumos = filterDoubles predicates.isSunOS;
|
||||||
netbsd = filterDoubles (matchAttrs { kernel = parse.kernels.netbsd; });
|
linux = filterDoubles predicates.isLinux;
|
||||||
openbsd = filterDoubles (matchAttrs { kernel = parse.kernels.openbsd; });
|
netbsd = filterDoubles predicates.isNetBSD;
|
||||||
unix = filterDoubles parse.isUnix;
|
openbsd = filterDoubles predicates.isOpenBSD;
|
||||||
|
unix = filterDoubles predicates.isUnix;
|
||||||
|
|
||||||
mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux"];
|
mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux"];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
# These can be passed to nixpkgs as either the `localSystem` or
|
||||||
|
# `crossSystem`. They are put here for user convenience, but also used by cross
|
||||||
|
# tests and linux cross stdenv building, so handle with care!
|
||||||
|
{ lib }:
|
||||||
|
let platforms = import ./platforms.nix { inherit lib; }; in
|
||||||
|
|
||||||
|
rec {
|
||||||
|
#
|
||||||
|
# Linux
|
||||||
|
#
|
||||||
|
|
||||||
|
sheevaplug = rec {
|
||||||
|
config = "armv5tel-unknown-linux-gnueabi";
|
||||||
|
bigEndian = false;
|
||||||
|
arch = "armv5tel";
|
||||||
|
float = "soft";
|
||||||
|
withTLS = true;
|
||||||
|
libc = "glibc";
|
||||||
|
platform = platforms.sheevaplug;
|
||||||
|
openssl.system = "linux-generic32";
|
||||||
|
inherit (platform) gcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
raspberryPi = rec {
|
||||||
|
config = "armv6l-unknown-linux-gnueabihf";
|
||||||
|
bigEndian = false;
|
||||||
|
arch = "armv6l";
|
||||||
|
float = "hard";
|
||||||
|
fpu = "vfp";
|
||||||
|
withTLS = true;
|
||||||
|
libc = "glibc";
|
||||||
|
platform = platforms.raspberrypi;
|
||||||
|
openssl.system = "linux-generic32";
|
||||||
|
inherit (platform) gcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
armv7l-hf-multiplatform = rec {
|
||||||
|
config = "arm-unknown-linux-gnueabihf";
|
||||||
|
bigEndian = false;
|
||||||
|
arch = "armv7-a";
|
||||||
|
float = "hard";
|
||||||
|
fpu = "vfpv3-d16";
|
||||||
|
withTLS = true;
|
||||||
|
libc = "glibc";
|
||||||
|
platform = platforms.armv7l-hf-multiplatform;
|
||||||
|
openssl.system = "linux-generic32";
|
||||||
|
inherit (platform) gcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
aarch64-multiplatform = rec {
|
||||||
|
config = "aarch64-unknown-linux-gnu";
|
||||||
|
bigEndian = false;
|
||||||
|
arch = "aarch64";
|
||||||
|
withTLS = true;
|
||||||
|
libc = "glibc";
|
||||||
|
platform = platforms.aarch64-multiplatform;
|
||||||
|
inherit (platform) gcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
scaleway-c1 = armv7l-hf-multiplatform // rec {
|
||||||
|
platform = platforms.scaleway-c1;
|
||||||
|
inherit (platform) gcc;
|
||||||
|
inherit (gcc) fpu;
|
||||||
|
};
|
||||||
|
|
||||||
|
pogoplug4 = rec {
|
||||||
|
arch = "armv5tel";
|
||||||
|
config = "armv5tel-softfloat-linux-gnueabi";
|
||||||
|
float = "soft";
|
||||||
|
|
||||||
|
platform = platforms.pogoplug4;
|
||||||
|
|
||||||
|
inherit (platform) gcc;
|
||||||
|
libc = "glibc";
|
||||||
|
|
||||||
|
withTLS = true;
|
||||||
|
openssl.system = "linux-generic32";
|
||||||
|
};
|
||||||
|
|
||||||
|
fuloongminipc = rec {
|
||||||
|
config = "mips64el-unknown-linux-gnu";
|
||||||
|
bigEndian = false;
|
||||||
|
arch = "mips";
|
||||||
|
float = "hard";
|
||||||
|
withTLS = true;
|
||||||
|
libc = "glibc";
|
||||||
|
platform = platforms.fuloong2f_n32;
|
||||||
|
openssl.system = "linux-generic32";
|
||||||
|
inherit (platform) gcc;
|
||||||
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
# Darwin
|
||||||
|
#
|
||||||
|
|
||||||
|
iphone64 = {
|
||||||
|
config = "aarch64-apple-darwin14";
|
||||||
|
arch = "arm64";
|
||||||
|
libc = "libSystem";
|
||||||
|
platform = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
iphone32 = {
|
||||||
|
config = "arm-apple-darwin10";
|
||||||
|
arch = "armv7-a";
|
||||||
|
libc = "libSystem";
|
||||||
|
platform = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
# Windows
|
||||||
|
#
|
||||||
|
|
||||||
|
# 32 bit mingw-w64
|
||||||
|
mingw32 = {
|
||||||
|
config = "i686-pc-mingw32";
|
||||||
|
arch = "x86"; # Irrelevant
|
||||||
|
libc = "msvcrt"; # This distinguishes the mingw (non posix) toolchain
|
||||||
|
platform = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
# 64 bit mingw-w64
|
||||||
|
mingwW64 = {
|
||||||
|
# That's the triplet they use in the mingw-w64 docs.
|
||||||
|
config = "x86_64-pc-mingw32";
|
||||||
|
arch = "x86_64"; # Irrelevant
|
||||||
|
libc = "msvcrt"; # This distinguishes the mingw (non posix) toolchain
|
||||||
|
platform = {};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{ lib }:
|
||||||
|
with import ./parse.nix { inherit lib; };
|
||||||
|
with lib.attrsets;
|
||||||
|
with lib.lists;
|
||||||
|
|
||||||
|
rec {
|
||||||
|
patterns = rec {
|
||||||
|
"32bit" = { cpu = { bits = 32; }; };
|
||||||
|
"64bit" = { cpu = { bits = 64; }; };
|
||||||
|
i686 = { cpu = cpuTypes.i686; };
|
||||||
|
x86_64 = { cpu = cpuTypes.x86_64; };
|
||||||
|
PowerPC = { cpu = cpuTypes.powerpc; };
|
||||||
|
x86 = { cpu = { family = "x86"; }; };
|
||||||
|
Arm = { cpu = { family = "arm"; }; };
|
||||||
|
Aarch64 = { cpu = { family = "aarch64"; }; };
|
||||||
|
Mips = { cpu = { family = "mips"; }; };
|
||||||
|
BigEndian = { cpu = { significantByte = significantBytes.bigEndian; }; };
|
||||||
|
LittleEndian = { cpu = { significantByte = significantBytes.littleEndian; }; };
|
||||||
|
|
||||||
|
BSD = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
|
||||||
|
Unix = [ BSD Darwin Linux SunOS Hurd Cygwin ];
|
||||||
|
|
||||||
|
Darwin = { kernel = kernels.darwin; };
|
||||||
|
Linux = { kernel = kernels.linux; };
|
||||||
|
SunOS = { kernel = kernels.solaris; };
|
||||||
|
FreeBSD = { kernel = kernels.freebsd; };
|
||||||
|
Hurd = { kernel = kernels.hurd; };
|
||||||
|
NetBSD = { kernel = kernels.netbsd; };
|
||||||
|
OpenBSD = { kernel = kernels.openbsd; };
|
||||||
|
Windows = { kernel = kernels.windows; };
|
||||||
|
Cygwin = { kernel = kernels.windows; abi = abis.cygnus; };
|
||||||
|
MinGW = { kernel = kernels.windows; abi = abis.gnu; };
|
||||||
|
};
|
||||||
|
|
||||||
|
matchAnyAttrs = patterns:
|
||||||
|
if builtins.isList patterns then attrs: any (pattern: matchAttrs pattern attrs) patterns
|
||||||
|
else matchAttrs patterns;
|
||||||
|
|
||||||
|
predicates = mapAttrs'
|
||||||
|
(name: value: nameValuePair ("is" + name) (matchAnyAttrs value))
|
||||||
|
patterns;
|
||||||
|
}
|
||||||
+57
-57
@@ -1,15 +1,19 @@
|
|||||||
# Define the list of system with their properties. Only systems tested for
|
# Define the list of system with their properties.
|
||||||
# Nixpkgs are listed below
|
#
|
||||||
|
# See https://clang.llvm.org/docs/CrossCompilation.html and
|
||||||
with import ../lists.nix;
|
# http://llvm.org/docs/doxygen/html/Triple_8cpp_source.html especially
|
||||||
with import ../types.nix;
|
# Triple::normalize. Parsing should essentially act as a more conservative
|
||||||
with import ../attrsets.nix;
|
# version of that last function.
|
||||||
|
{ lib }:
|
||||||
|
with lib.lists;
|
||||||
|
with lib.types;
|
||||||
|
with lib.attrsets;
|
||||||
|
with (import ./inspect.nix { inherit lib; }).predicates;
|
||||||
|
|
||||||
let
|
let
|
||||||
lib = import ../default.nix;
|
|
||||||
setTypesAssert = type: pred:
|
setTypesAssert = type: pred:
|
||||||
mapAttrs (name: value:
|
mapAttrs (name: value:
|
||||||
#assert pred value;
|
assert pred value;
|
||||||
setType type ({ inherit name; } // value));
|
setType type ({ inherit name; } // value));
|
||||||
setTypes = type: setTypesAssert type (_: true);
|
setTypes = type: setTypesAssert type (_: true);
|
||||||
|
|
||||||
@@ -23,7 +27,6 @@ rec {
|
|||||||
littleEndian = {};
|
littleEndian = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
isCpuType = isType "cpu-type";
|
isCpuType = isType "cpu-type";
|
||||||
cpuTypes = with significantBytes; setTypesAssert "cpu-type"
|
cpuTypes = with significantBytes; setTypesAssert "cpu-type"
|
||||||
(x: elem x.bits [8 16 32 64 128]
|
(x: elem x.bits [8 16 32 64 128]
|
||||||
@@ -36,17 +39,18 @@ rec {
|
|||||||
armv6l = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
armv6l = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
||||||
armv7a = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
armv7a = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
||||||
armv7l = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
armv7l = { bits = 32; significantByte = littleEndian; family = "arm"; };
|
||||||
aarch64 = { bits = 64; significantByte = littleEndian; family = "arm"; };
|
aarch64 = { bits = 64; significantByte = littleEndian; family = "aarch64"; };
|
||||||
i686 = { bits = 32; significantByte = littleEndian; family = "x86"; };
|
i686 = { bits = 32; significantByte = littleEndian; family = "x86"; };
|
||||||
x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; };
|
x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; };
|
||||||
mips64el = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
mips64el = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
||||||
powerpc = { bits = 32; significantByte = bigEndian; family = "powerpc"; };
|
powerpc = { bits = 32; significantByte = bigEndian; family = "power"; };
|
||||||
};
|
};
|
||||||
|
|
||||||
isVendor = isType "vendor";
|
isVendor = isType "vendor";
|
||||||
vendors = setTypes "vendor" {
|
vendors = setTypes "vendor" {
|
||||||
apple = {};
|
apple = {};
|
||||||
pc = {};
|
pc = {};
|
||||||
|
|
||||||
unknown = {};
|
unknown = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -56,39 +60,45 @@ rec {
|
|||||||
elf = {};
|
elf = {};
|
||||||
macho = {};
|
macho = {};
|
||||||
pe = {};
|
pe = {};
|
||||||
|
|
||||||
unknown = {};
|
unknown = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
isKernelFamily = isType "kernel-family";
|
isKernelFamily = isType "kernel-family";
|
||||||
kernelFamilies = setTypes "kernel-family" {
|
kernelFamilies = setTypes "kernel-family" {
|
||||||
bsd = {};
|
bsd = {};
|
||||||
unix = {};
|
|
||||||
windows-nt = {};
|
|
||||||
dos = {};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
isKernel = x: isType "kernel" x;
|
isKernel = x: isType "kernel" x;
|
||||||
kernels = with execFormats; with kernelFamilies; setTypesAssert "kernel"
|
kernels = with execFormats; with kernelFamilies; setTypesAssert "kernel"
|
||||||
(x: isExecFormat x.execFormat && all isKernelFamily (attrValues x.families))
|
(x: isExecFormat x.execFormat && all isKernelFamily (attrValues x.families))
|
||||||
{
|
{
|
||||||
cygwin = { execFormat = pe; families = { inherit /*unix*/ windows-nt; }; };
|
darwin = { execFormat = macho; families = { }; };
|
||||||
darwin = { execFormat = macho; families = { inherit unix; }; };
|
freebsd = { execFormat = elf; families = { inherit bsd; }; };
|
||||||
freebsd = { execFormat = elf; families = { inherit unix bsd; }; };
|
hurd = { execFormat = elf; families = { }; };
|
||||||
linux = { execFormat = elf; families = { inherit unix; }; };
|
linux = { execFormat = elf; families = { }; };
|
||||||
netbsd = { execFormat = elf; families = { inherit unix bsd; }; };
|
netbsd = { execFormat = elf; families = { inherit bsd; }; };
|
||||||
none = { execFormat = unknown; families = { inherit unix; }; };
|
none = { execFormat = unknown; families = { }; };
|
||||||
openbsd = { execFormat = elf; families = { inherit unix bsd; }; };
|
openbsd = { execFormat = elf; families = { inherit bsd; }; };
|
||||||
solaris = { execFormat = elf; families = { inherit unix; }; };
|
solaris = { execFormat = elf; families = { }; };
|
||||||
win32 = { execFormat = pe; families = { inherit dos; }; };
|
windows = { execFormat = pe; families = { }; };
|
||||||
|
} // { # aliases
|
||||||
|
# TODO(@Ericson2314): Handle these Darwin version suffixes more generally.
|
||||||
|
darwin10 = kernels.darwin;
|
||||||
|
darwin14 = kernels.darwin;
|
||||||
|
win32 = kernels.windows;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
isAbi = isType "abi";
|
isAbi = isType "abi";
|
||||||
abis = setTypes "abi" {
|
abis = setTypes "abi" {
|
||||||
|
cygnus = {};
|
||||||
gnu = {};
|
gnu = {};
|
||||||
msvc = {};
|
msvc = {};
|
||||||
eabi = {};
|
eabi = {};
|
||||||
androideabi = {};
|
androideabi = {};
|
||||||
|
gnueabi = {};
|
||||||
|
gnueabihf = {};
|
||||||
|
|
||||||
unknown = {};
|
unknown = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -99,27 +109,22 @@ rec {
|
|||||||
inherit cpu vendor kernel abi;
|
inherit cpu vendor kernel abi;
|
||||||
};
|
};
|
||||||
|
|
||||||
is64Bit = matchAttrs { cpu = { bits = 64; }; };
|
|
||||||
is32Bit = matchAttrs { cpu = { bits = 32; }; };
|
|
||||||
isi686 = matchAttrs { cpu = cpuTypes.i686; };
|
|
||||||
isx86_64 = matchAttrs { cpu = cpuTypes.x86_64; };
|
|
||||||
|
|
||||||
isDarwin = matchAttrs { kernel = kernels.darwin; };
|
|
||||||
isLinux = matchAttrs { kernel = kernels.linux; };
|
|
||||||
isUnix = matchAttrs { kernel = { families = { inherit (kernelFamilies) unix; }; }; };
|
|
||||||
isWindows = s: matchAttrs { kernel = { families = { inherit (kernelFamilies) windows-nt; }; }; } s
|
|
||||||
|| matchAttrs { kernel = { families = { inherit (kernelFamilies) dos; }; }; } s;
|
|
||||||
|
|
||||||
|
|
||||||
mkSkeletonFromList = l: {
|
mkSkeletonFromList = l: {
|
||||||
"2" = { cpu = elemAt l 0; kernel = elemAt l 1; };
|
"2" = # We only do 2-part hacks for things Nix already supports
|
||||||
"4" = { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; };
|
if elemAt l 1 == "cygwin"
|
||||||
|
then { cpu = elemAt l 0; kernel = "windows"; abi = "cygnus"; }
|
||||||
|
else if elemAt l 1 == "gnu"
|
||||||
|
then { cpu = elemAt l 0; kernel = "hurd"; abi = "gnu"; }
|
||||||
|
else { cpu = elemAt l 0; kernel = elemAt l 1; };
|
||||||
"3" = # Awkwards hacks, beware!
|
"3" = # Awkwards hacks, beware!
|
||||||
if elemAt l 1 == "apple"
|
if elemAt l 1 == "apple"
|
||||||
then { cpu = elemAt l 0; vendor = "apple"; kernel = elemAt l 2; }
|
then { cpu = elemAt l 0; vendor = "apple"; kernel = elemAt l 2; }
|
||||||
else if (elemAt l 1 == "linux") || (elemAt l 2 == "gnu")
|
else if (elemAt l 1 == "linux") || (elemAt l 2 == "gnu")
|
||||||
then { cpu = elemAt l 0; kernel = elemAt l 1; abi = elemAt l 2; }
|
then { cpu = elemAt l 0; kernel = elemAt l 1; abi = elemAt l 2; }
|
||||||
|
else if (elemAt l 2 == "mingw32") # autotools breaks on -gnu for window
|
||||||
|
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; abi = "gnu"; }
|
||||||
else throw "Target specification with 3 components is ambiguous";
|
else throw "Target specification with 3 components is ambiguous";
|
||||||
|
"4" = { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; };
|
||||||
}.${toString (length l)}
|
}.${toString (length l)}
|
||||||
or (throw "system string has invalid number of hyphen-separated components");
|
or (throw "system string has invalid number of hyphen-separated components");
|
||||||
|
|
||||||
@@ -132,39 +137,34 @@ rec {
|
|||||||
, # Also inferred below
|
, # Also inferred below
|
||||||
abi ? assert false; null
|
abi ? assert false; null
|
||||||
} @ args: let
|
} @ args: let
|
||||||
getCpu = name:
|
getCpu = name: cpuTypes.${name} or (throw "Unknown CPU type: ${name}");
|
||||||
attrByPath [name] (throw "Unknown CPU type: ${name}")
|
getVendor = name: vendors.${name} or (throw "Unknown vendor: ${name}");
|
||||||
cpuTypes;
|
getKernel = name: kernels.${name} or (throw "Unknown kernel: ${name}");
|
||||||
getVendor = name:
|
getAbi = name: abis.${name} or (throw "Unknown ABI: ${name}");
|
||||||
attrByPath [name] (throw "Unknown vendor: ${name}")
|
|
||||||
vendors;
|
|
||||||
getKernel = name:
|
|
||||||
attrByPath [name] (throw "Unknown kernel: ${name}")
|
|
||||||
kernels;
|
|
||||||
getAbi = name:
|
|
||||||
attrByPath [name] (throw "Unknown ABI: ${name}")
|
|
||||||
abis;
|
|
||||||
|
|
||||||
system = rec {
|
parsed = rec {
|
||||||
cpu = getCpu args.cpu;
|
cpu = getCpu args.cpu;
|
||||||
vendor =
|
vendor =
|
||||||
/**/ if args ? vendor then getVendor args.vendor
|
/**/ if args ? vendor then getVendor args.vendor
|
||||||
else if isDarwin system then vendors.apple
|
else if isDarwin parsed then vendors.apple
|
||||||
else if isWindows system then vendors.pc
|
else if isWindows parsed then vendors.pc
|
||||||
else vendors.unknown;
|
else vendors.unknown;
|
||||||
kernel = getKernel args.kernel;
|
kernel = getKernel args.kernel;
|
||||||
abi =
|
abi =
|
||||||
/**/ if args ? abi then getAbi args.abi
|
/**/ if args ? abi then getAbi args.abi
|
||||||
else if isLinux system then abis.gnu
|
else if isLinux parsed then abis.gnu
|
||||||
else if isWindows system then abis.gnu
|
else if isWindows parsed then abis.gnu
|
||||||
else abis.unknown;
|
else abis.unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
in mkSystem system;
|
in mkSystem parsed;
|
||||||
|
|
||||||
mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s));
|
mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s));
|
||||||
|
|
||||||
doubleFromSystem = { cpu, vendor, kernel, abi, ... }: "${cpu.name}-${kernel.name}";
|
doubleFromSystem = { cpu, vendor, kernel, abi, ... }:
|
||||||
|
if abi == abis.cygnus
|
||||||
|
then "${cpu.name}-cygwin"
|
||||||
|
else "${cpu.name}-${kernel.name}";
|
||||||
|
|
||||||
tripleFromSystem = { cpu, vendor, kernel, abi, ... } @ sys: assert isSystem sys; let
|
tripleFromSystem = { cpu, vendor, kernel, abi, ... } @ sys: assert isSystem sys; let
|
||||||
optAbi = lib.optionalString (abi != abis.unknown) "-${abi.name}";
|
optAbi = lib.optionalString (abi != abis.unknown) "-${abi.name}";
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{ lib }:
|
||||||
rec {
|
rec {
|
||||||
pcBase = {
|
pcBase = {
|
||||||
name = "pc";
|
name = "pc";
|
||||||
@@ -21,6 +22,39 @@ rec {
|
|||||||
kernelAutoModules = false;
|
kernelAutoModules = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pogoplug4 = {
|
||||||
|
name = "pogoplug4";
|
||||||
|
|
||||||
|
gcc = {
|
||||||
|
arch = "armv5te";
|
||||||
|
float = "soft";
|
||||||
|
};
|
||||||
|
|
||||||
|
kernelMajor = "2.6";
|
||||||
|
kernelHeadersBaseConfig = "multi_v5_defconfig";
|
||||||
|
kernelBaseConfig = "multi_v5_defconfig";
|
||||||
|
kernelArch = "arm";
|
||||||
|
kernelAutoModules = false;
|
||||||
|
kernelExtraConfig =
|
||||||
|
''
|
||||||
|
# Ubi for the mtd
|
||||||
|
MTD_UBI y
|
||||||
|
UBIFS_FS y
|
||||||
|
UBIFS_FS_XATTR y
|
||||||
|
UBIFS_FS_ADVANCED_COMPR y
|
||||||
|
UBIFS_FS_LZO y
|
||||||
|
UBIFS_FS_ZLIB y
|
||||||
|
UBIFS_FS_DEBUG n
|
||||||
|
'';
|
||||||
|
kernelMakeFlags = [ "LOADADDR=0x8000" ];
|
||||||
|
kernelTarget = "uImage";
|
||||||
|
# TODO reenable once manual-config's config actually builds a .dtb and this is checked to be working
|
||||||
|
#kernelDTB = true;
|
||||||
|
|
||||||
|
# XXX can be anything non-null, pkgs actually only cares if it is set or not
|
||||||
|
uboot = "pogoplug4";
|
||||||
|
};
|
||||||
|
|
||||||
sheevaplug = {
|
sheevaplug = {
|
||||||
name = "sheevaplug";
|
name = "sheevaplug";
|
||||||
kernelMajor = "2.6";
|
kernelMajor = "2.6";
|
||||||
@@ -222,6 +256,10 @@ rec {
|
|||||||
arch = "armv6";
|
arch = "armv6";
|
||||||
fpu = "vfp";
|
fpu = "vfp";
|
||||||
float = "hard";
|
float = "hard";
|
||||||
|
# TODO(@Ericson2314) what is this and is it a good idea? It was
|
||||||
|
# used in some cross compilation examples but not others.
|
||||||
|
#
|
||||||
|
# abi = "aapcs-linux";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -307,6 +345,43 @@ rec {
|
|||||||
uboot = null;
|
uboot = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
scaleway-c1 = armv7l-hf-multiplatform // {
|
||||||
|
gcc = {
|
||||||
|
cpu = "cortex-a9";
|
||||||
|
fpu = "vfpv3";
|
||||||
|
float = "hard";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
utilite = {
|
||||||
|
name = "utilite";
|
||||||
|
kernelMajor = "2.6";
|
||||||
|
kernelHeadersBaseConfig = "multi_v7_defconfig";
|
||||||
|
kernelBaseConfig = "multi_v7_defconfig";
|
||||||
|
kernelArch = "arm";
|
||||||
|
kernelAutoModules = false;
|
||||||
|
kernelExtraConfig =
|
||||||
|
''
|
||||||
|
# Ubi for the mtd
|
||||||
|
MTD_UBI y
|
||||||
|
UBIFS_FS y
|
||||||
|
UBIFS_FS_XATTR y
|
||||||
|
UBIFS_FS_ADVANCED_COMPR y
|
||||||
|
UBIFS_FS_LZO y
|
||||||
|
UBIFS_FS_ZLIB y
|
||||||
|
UBIFS_FS_DEBUG n
|
||||||
|
'';
|
||||||
|
kernelMakeFlags = [ "LOADADDR=0x10800000" ];
|
||||||
|
kernelTarget = "uImage";
|
||||||
|
kernelDTB = true;
|
||||||
|
uboot = true; #XXX: any non-null value here is needed so that mkimage is present to build kernelTarget uImage
|
||||||
|
gcc = {
|
||||||
|
cpu = "cortex-a9";
|
||||||
|
fpu = "neon";
|
||||||
|
float = "hard";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
guruplug = sheevaplug // {
|
guruplug = sheevaplug // {
|
||||||
# Define `CONFIG_MACH_GURUPLUG' (see
|
# Define `CONFIG_MACH_GURUPLUG' (see
|
||||||
# <http://kerneltrap.org/mailarchive/git-commits-head/2010/5/19/33618>)
|
# <http://kerneltrap.org/mailarchive/git-commits-head/2010/5/19/33618>)
|
||||||
@@ -390,7 +465,10 @@ rec {
|
|||||||
'';
|
'';
|
||||||
kernelTarget = "vmlinux";
|
kernelTarget = "vmlinux";
|
||||||
uboot = null;
|
uboot = null;
|
||||||
gcc.arch = "loongson2f";
|
gcc = {
|
||||||
|
arch = "loongson2f";
|
||||||
|
abi = "n32";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
beaglebone = armv7l-hf-multiplatform // {
|
beaglebone = armv7l-hf-multiplatform // {
|
||||||
@@ -466,6 +544,13 @@ rec {
|
|||||||
|
|
||||||
# Cavium ThunderX stuff.
|
# Cavium ThunderX stuff.
|
||||||
PCI_HOST_THUNDER_ECAM y
|
PCI_HOST_THUNDER_ECAM y
|
||||||
|
|
||||||
|
# Nvidia Tegra stuff.
|
||||||
|
PCI_TEGRA y
|
||||||
|
|
||||||
|
# The default (=y) forces us to have the XHCI firmware available in initrd,
|
||||||
|
# which our initrd builder can't currently do easily.
|
||||||
|
USB_XHCI_TEGRA m
|
||||||
'';
|
'';
|
||||||
uboot = null;
|
uboot = null;
|
||||||
kernelTarget = "Image";
|
kernelTarget = "Image";
|
||||||
|
|||||||
-290
@@ -1,290 +0,0 @@
|
|||||||
# to run these tests:
|
|
||||||
# nix-instantiate --eval --strict nixpkgs/lib/tests.nix
|
|
||||||
# if the resulting list is empty, all tests passed
|
|
||||||
let inherit (builtins) add; in
|
|
||||||
with import ./default.nix;
|
|
||||||
|
|
||||||
runTests {
|
|
||||||
|
|
||||||
testId = {
|
|
||||||
expr = id 1;
|
|
||||||
expected = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
testConst = {
|
|
||||||
expr = const 2 3;
|
|
||||||
expected = 2;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
testOr = {
|
|
||||||
expr = or true false;
|
|
||||||
expected = true;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
testAnd = {
|
|
||||||
expr = and true false;
|
|
||||||
expected = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
testFix = {
|
|
||||||
expr = fix (x: {a = if x ? a then "a" else "b";});
|
|
||||||
expected = {a = "a";};
|
|
||||||
};
|
|
||||||
|
|
||||||
testConcatMapStrings = {
|
|
||||||
expr = concatMapStrings (x: x + ";") ["a" "b" "c"];
|
|
||||||
expected = "a;b;c;";
|
|
||||||
};
|
|
||||||
|
|
||||||
testConcatStringsSep = {
|
|
||||||
expr = concatStringsSep "," ["a" "b" "c"];
|
|
||||||
expected = "a,b,c";
|
|
||||||
};
|
|
||||||
|
|
||||||
testFilter = {
|
|
||||||
expr = filter (x: x != "a") ["a" "b" "c" "a"];
|
|
||||||
expected = ["b" "c"];
|
|
||||||
};
|
|
||||||
|
|
||||||
testFold =
|
|
||||||
let
|
|
||||||
f = op: fold: fold op 0 (range 0 100);
|
|
||||||
# fold with associative operator
|
|
||||||
assoc = f builtins.add;
|
|
||||||
# fold with non-associative operator
|
|
||||||
nonAssoc = f builtins.sub;
|
|
||||||
in {
|
|
||||||
expr = {
|
|
||||||
assocRight = assoc foldr;
|
|
||||||
# right fold with assoc operator is same as left fold
|
|
||||||
assocRightIsLeft = assoc foldr == assoc foldl;
|
|
||||||
nonAssocRight = nonAssoc foldr;
|
|
||||||
nonAssocLeft = nonAssoc foldl;
|
|
||||||
# with non-assoc operator the fold results are not the same
|
|
||||||
nonAssocRightIsNotLeft = nonAssoc foldl != nonAssoc foldr;
|
|
||||||
# fold is an alias for foldr
|
|
||||||
foldIsRight = nonAssoc fold == nonAssoc foldr;
|
|
||||||
};
|
|
||||||
expected = {
|
|
||||||
assocRight = 5050;
|
|
||||||
assocRightIsLeft = true;
|
|
||||||
nonAssocRight = 50;
|
|
||||||
nonAssocLeft = (-5050);
|
|
||||||
nonAssocRightIsNotLeft = true;
|
|
||||||
foldIsRight = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
testTake = testAllTrue [
|
|
||||||
([] == (take 0 [ 1 2 3 ]))
|
|
||||||
([1] == (take 1 [ 1 2 3 ]))
|
|
||||||
([ 1 2 ] == (take 2 [ 1 2 3 ]))
|
|
||||||
([ 1 2 3 ] == (take 3 [ 1 2 3 ]))
|
|
||||||
([ 1 2 3 ] == (take 4 [ 1 2 3 ]))
|
|
||||||
];
|
|
||||||
|
|
||||||
testFoldAttrs = {
|
|
||||||
expr = foldAttrs (n: a: [n] ++ a) [] [
|
|
||||||
{ a = 2; b = 7; }
|
|
||||||
{ a = 3; c = 8; }
|
|
||||||
];
|
|
||||||
expected = { a = [ 2 3 ]; b = [7]; c = [8];};
|
|
||||||
};
|
|
||||||
|
|
||||||
testOverridableDelayableArgsTest = {
|
|
||||||
expr =
|
|
||||||
let res1 = defaultOverridableDelayableArgs id {};
|
|
||||||
res2 = defaultOverridableDelayableArgs id { a = 7; };
|
|
||||||
res3 = let x = defaultOverridableDelayableArgs id { a = 7; };
|
|
||||||
in (x.merge) { b = 10; };
|
|
||||||
res4 = let x = defaultOverridableDelayableArgs id { a = 7; };
|
|
||||||
in (x.merge) ( x: { b = 10; });
|
|
||||||
res5 = let x = defaultOverridableDelayableArgs id { a = 7; };
|
|
||||||
in (x.merge) ( x: { a = add x.a 3; });
|
|
||||||
res6 = let x = defaultOverridableDelayableArgs id { a = 7; mergeAttrBy = { a = add; }; };
|
|
||||||
y = x.merge {};
|
|
||||||
in (y.merge) { a = 10; };
|
|
||||||
|
|
||||||
resRem7 = res6.replace (a: removeAttrs a ["a"]);
|
|
||||||
|
|
||||||
resReplace6 = let x = defaultOverridableDelayableArgs id { a = 7; mergeAttrBy = { a = add; }; };
|
|
||||||
x2 = x.merge { a = 20; }; # now we have 27
|
|
||||||
in (x2.replace) { a = 10; }; # and override the value by 10
|
|
||||||
|
|
||||||
# fixed tests (delayed args): (when using them add some comments, please)
|
|
||||||
resFixed1 =
|
|
||||||
let x = defaultOverridableDelayableArgs id ( x: { a = 7; c = x.fixed.b; });
|
|
||||||
y = x.merge (x: { name = "name-${builtins.toString x.fixed.c}"; });
|
|
||||||
in (y.merge) { b = 10; };
|
|
||||||
strip = attrs: removeAttrs attrs ["merge" "replace"];
|
|
||||||
in all id
|
|
||||||
[ ((strip res1) == { })
|
|
||||||
((strip res2) == { a = 7; })
|
|
||||||
((strip res3) == { a = 7; b = 10; })
|
|
||||||
((strip res4) == { a = 7; b = 10; })
|
|
||||||
((strip res5) == { a = 10; })
|
|
||||||
((strip res6) == { a = 17; })
|
|
||||||
((strip resRem7) == {})
|
|
||||||
((strip resFixed1) == { a = 7; b = 10; c =10; name = "name-10"; })
|
|
||||||
];
|
|
||||||
expected = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
testSort = {
|
|
||||||
expr = sort builtins.lessThan [ 40 2 30 42 ];
|
|
||||||
expected = [2 30 40 42];
|
|
||||||
};
|
|
||||||
|
|
||||||
testToIntShouldConvertStringToInt = {
|
|
||||||
expr = toInt "27";
|
|
||||||
expected = 27;
|
|
||||||
};
|
|
||||||
|
|
||||||
testToIntShouldThrowErrorIfItCouldNotConvertToInt = {
|
|
||||||
expr = builtins.tryEval (toInt "\"foo\"");
|
|
||||||
expected = { success = false; value = false; };
|
|
||||||
};
|
|
||||||
|
|
||||||
testHasAttrByPathTrue = {
|
|
||||||
expr = hasAttrByPath ["a" "b"] { a = { b = "yey"; }; };
|
|
||||||
expected = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
testHasAttrByPathFalse = {
|
|
||||||
expr = hasAttrByPath ["a" "b"] { a = { c = "yey"; }; };
|
|
||||||
expected = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Generator tests */
|
|
||||||
# these tests assume attributes are converted to lists
|
|
||||||
# in alphabetical order
|
|
||||||
|
|
||||||
testMkKeyValueDefault = {
|
|
||||||
expr = generators.mkKeyValueDefault ":" "f:oo" "bar";
|
|
||||||
expected = ''f\:oo:bar'';
|
|
||||||
};
|
|
||||||
|
|
||||||
testToKeyValue = {
|
|
||||||
expr = generators.toKeyValue {} {
|
|
||||||
key = "value";
|
|
||||||
"other=key" = "baz";
|
|
||||||
};
|
|
||||||
expected = ''
|
|
||||||
key=value
|
|
||||||
other\=key=baz
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
testToINIEmpty = {
|
|
||||||
expr = generators.toINI {} {};
|
|
||||||
expected = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
testToINIEmptySection = {
|
|
||||||
expr = generators.toINI {} { foo = {}; bar = {}; };
|
|
||||||
expected = ''
|
|
||||||
[bar]
|
|
||||||
|
|
||||||
[foo]
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
testToINIDefaultEscapes = {
|
|
||||||
expr = generators.toINI {} {
|
|
||||||
"no [ and ] allowed unescaped" = {
|
|
||||||
"and also no = in keys" = 42;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
expected = ''
|
|
||||||
[no \[ and \] allowed unescaped]
|
|
||||||
and also no \= in keys=42
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
testToINIDefaultFull = {
|
|
||||||
expr = generators.toINI {} {
|
|
||||||
"section 1" = {
|
|
||||||
attribute1 = 5;
|
|
||||||
x = "Me-se JarJar Binx";
|
|
||||||
};
|
|
||||||
"foo[]" = {
|
|
||||||
"he\\h=he" = "this is okay";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
expected = ''
|
|
||||||
[foo\[\]]
|
|
||||||
he\h\=he=this is okay
|
|
||||||
|
|
||||||
[section 1]
|
|
||||||
attribute1=5
|
|
||||||
x=Me-se JarJar Binx
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
/* right now only invocation check */
|
|
||||||
testToJSONSimple =
|
|
||||||
let val = {
|
|
||||||
foobar = [ "baz" 1 2 3 ];
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
expr = generators.toJSON {} val;
|
|
||||||
# trivial implementation
|
|
||||||
expected = builtins.toJSON val;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* right now only invocation check */
|
|
||||||
testToYAMLSimple =
|
|
||||||
let val = {
|
|
||||||
list = [ { one = 1; } { two = 2; } ];
|
|
||||||
all = 42;
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
expr = generators.toYAML {} val;
|
|
||||||
# trivial implementation
|
|
||||||
expected = builtins.toJSON val;
|
|
||||||
};
|
|
||||||
|
|
||||||
testSplitStringsSimple = {
|
|
||||||
expr = strings.splitString "." "a.b.c.d";
|
|
||||||
expected = [ "a" "b" "c" "d" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
testSplitStringsEmpty = {
|
|
||||||
expr = strings.splitString "." "a..b";
|
|
||||||
expected = [ "a" "" "b" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
testSplitStringsOne = {
|
|
||||||
expr = strings.splitString ":" "a.b";
|
|
||||||
expected = [ "a.b" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
testSplitStringsNone = {
|
|
||||||
expr = strings.splitString "." "";
|
|
||||||
expected = [ "" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
testSplitStringsFirstEmpty = {
|
|
||||||
expr = strings.splitString "/" "/a/b/c";
|
|
||||||
expected = [ "" "a" "b" "c" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
testSplitStringsLastEmpty = {
|
|
||||||
expr = strings.splitString ":" "2001:db8:0:0042::8a2e:370:";
|
|
||||||
expected = [ "2001" "db8" "0" "0042" "" "8a2e" "370" "" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
testComposeExtensions = {
|
|
||||||
expr = let obj = makeExtensible (self: { foo = self.bar; });
|
|
||||||
f = self: super: { bar = false; baz = true; };
|
|
||||||
g = self: super: { bar = super.baz or false; };
|
|
||||||
f_o_g = composeExtensions f g;
|
|
||||||
composed = obj.extend f_o_g;
|
|
||||||
in composed.foo;
|
|
||||||
expected = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,361 @@
|
|||||||
|
# to run these tests:
|
||||||
|
# nix-instantiate --eval --strict nixpkgs/lib/tests/misc.nix
|
||||||
|
# if the resulting list is empty, all tests passed
|
||||||
|
with import ../default.nix;
|
||||||
|
|
||||||
|
runTests {
|
||||||
|
|
||||||
|
|
||||||
|
# TRIVIAL
|
||||||
|
|
||||||
|
testId = {
|
||||||
|
expr = id 1;
|
||||||
|
expected = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
testConst = {
|
||||||
|
expr = const 2 3;
|
||||||
|
expected = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
testOr = {
|
||||||
|
expr = or true false;
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
testAnd = {
|
||||||
|
expr = and true false;
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
testFix = {
|
||||||
|
expr = fix (x: {a = if x ? a then "a" else "b";});
|
||||||
|
expected = {a = "a";};
|
||||||
|
};
|
||||||
|
|
||||||
|
testComposeExtensions = {
|
||||||
|
expr = let obj = makeExtensible (self: { foo = self.bar; });
|
||||||
|
f = self: super: { bar = false; baz = true; };
|
||||||
|
g = self: super: { bar = super.baz or false; };
|
||||||
|
f_o_g = composeExtensions f g;
|
||||||
|
composed = obj.extend f_o_g;
|
||||||
|
in composed.foo;
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# STRINGS
|
||||||
|
|
||||||
|
testConcatMapStrings = {
|
||||||
|
expr = concatMapStrings (x: x + ";") ["a" "b" "c"];
|
||||||
|
expected = "a;b;c;";
|
||||||
|
};
|
||||||
|
|
||||||
|
testConcatStringsSep = {
|
||||||
|
expr = concatStringsSep "," ["a" "b" "c"];
|
||||||
|
expected = "a,b,c";
|
||||||
|
};
|
||||||
|
|
||||||
|
testSplitStringsSimple = {
|
||||||
|
expr = strings.splitString "." "a.b.c.d";
|
||||||
|
expected = [ "a" "b" "c" "d" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testSplitStringsEmpty = {
|
||||||
|
expr = strings.splitString "." "a..b";
|
||||||
|
expected = [ "a" "" "b" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testSplitStringsOne = {
|
||||||
|
expr = strings.splitString ":" "a.b";
|
||||||
|
expected = [ "a.b" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testSplitStringsNone = {
|
||||||
|
expr = strings.splitString "." "";
|
||||||
|
expected = [ "" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testSplitStringsFirstEmpty = {
|
||||||
|
expr = strings.splitString "/" "/a/b/c";
|
||||||
|
expected = [ "" "a" "b" "c" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testSplitStringsLastEmpty = {
|
||||||
|
expr = strings.splitString ":" "2001:db8:0:0042::8a2e:370:";
|
||||||
|
expected = [ "2001" "db8" "0" "0042" "" "8a2e" "370" "" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testIsStorePath = {
|
||||||
|
expr =
|
||||||
|
let goodPath =
|
||||||
|
"${builtins.storeDir}/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11";
|
||||||
|
in {
|
||||||
|
storePath = isStorePath goodPath;
|
||||||
|
storePathAppendix = isStorePath
|
||||||
|
"${goodPath}/bin/python";
|
||||||
|
nonAbsolute = isStorePath (concatStrings (tail (stringToCharacters goodPath)));
|
||||||
|
asPath = isStorePath (builtins.toPath goodPath);
|
||||||
|
otherPath = isStorePath "/something/else";
|
||||||
|
otherVals = {
|
||||||
|
attrset = isStorePath {};
|
||||||
|
list = isStorePath [];
|
||||||
|
int = isStorePath 42;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
expected = {
|
||||||
|
storePath = true;
|
||||||
|
storePathAppendix = false;
|
||||||
|
nonAbsolute = false;
|
||||||
|
asPath = true;
|
||||||
|
otherPath = false;
|
||||||
|
otherVals = {
|
||||||
|
attrset = false;
|
||||||
|
list = false;
|
||||||
|
int = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# LISTS
|
||||||
|
|
||||||
|
testFilter = {
|
||||||
|
expr = filter (x: x != "a") ["a" "b" "c" "a"];
|
||||||
|
expected = ["b" "c"];
|
||||||
|
};
|
||||||
|
|
||||||
|
testFold =
|
||||||
|
let
|
||||||
|
f = op: fold: fold op 0 (range 0 100);
|
||||||
|
# fold with associative operator
|
||||||
|
assoc = f builtins.add;
|
||||||
|
# fold with non-associative operator
|
||||||
|
nonAssoc = f builtins.sub;
|
||||||
|
in {
|
||||||
|
expr = {
|
||||||
|
assocRight = assoc foldr;
|
||||||
|
# right fold with assoc operator is same as left fold
|
||||||
|
assocRightIsLeft = assoc foldr == assoc foldl;
|
||||||
|
nonAssocRight = nonAssoc foldr;
|
||||||
|
nonAssocLeft = nonAssoc foldl;
|
||||||
|
# with non-assoc operator the fold results are not the same
|
||||||
|
nonAssocRightIsNotLeft = nonAssoc foldl != nonAssoc foldr;
|
||||||
|
# fold is an alias for foldr
|
||||||
|
foldIsRight = nonAssoc fold == nonAssoc foldr;
|
||||||
|
};
|
||||||
|
expected = {
|
||||||
|
assocRight = 5050;
|
||||||
|
assocRightIsLeft = true;
|
||||||
|
nonAssocRight = 50;
|
||||||
|
nonAssocLeft = (-5050);
|
||||||
|
nonAssocRightIsNotLeft = true;
|
||||||
|
foldIsRight = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testTake = testAllTrue [
|
||||||
|
([] == (take 0 [ 1 2 3 ]))
|
||||||
|
([1] == (take 1 [ 1 2 3 ]))
|
||||||
|
([ 1 2 ] == (take 2 [ 1 2 3 ]))
|
||||||
|
([ 1 2 3 ] == (take 3 [ 1 2 3 ]))
|
||||||
|
([ 1 2 3 ] == (take 4 [ 1 2 3 ]))
|
||||||
|
];
|
||||||
|
|
||||||
|
testFoldAttrs = {
|
||||||
|
expr = foldAttrs (n: a: [n] ++ a) [] [
|
||||||
|
{ a = 2; b = 7; }
|
||||||
|
{ a = 3; c = 8; }
|
||||||
|
];
|
||||||
|
expected = { a = [ 2 3 ]; b = [7]; c = [8];};
|
||||||
|
};
|
||||||
|
|
||||||
|
testSort = {
|
||||||
|
expr = sort builtins.lessThan [ 40 2 30 42 ];
|
||||||
|
expected = [2 30 40 42];
|
||||||
|
};
|
||||||
|
|
||||||
|
testToIntShouldConvertStringToInt = {
|
||||||
|
expr = toInt "27";
|
||||||
|
expected = 27;
|
||||||
|
};
|
||||||
|
|
||||||
|
testToIntShouldThrowErrorIfItCouldNotConvertToInt = {
|
||||||
|
expr = builtins.tryEval (toInt "\"foo\"");
|
||||||
|
expected = { success = false; value = false; };
|
||||||
|
};
|
||||||
|
|
||||||
|
testHasAttrByPathTrue = {
|
||||||
|
expr = hasAttrByPath ["a" "b"] { a = { b = "yey"; }; };
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
testHasAttrByPathFalse = {
|
||||||
|
expr = hasAttrByPath ["a" "b"] { a = { c = "yey"; }; };
|
||||||
|
expected = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# GENERATORS
|
||||||
|
# these tests assume attributes are converted to lists
|
||||||
|
# in alphabetical order
|
||||||
|
|
||||||
|
testMkKeyValueDefault = {
|
||||||
|
expr = generators.mkKeyValueDefault ":" "f:oo" "bar";
|
||||||
|
expected = ''f\:oo:bar'';
|
||||||
|
};
|
||||||
|
|
||||||
|
testToKeyValue = {
|
||||||
|
expr = generators.toKeyValue {} {
|
||||||
|
key = "value";
|
||||||
|
"other=key" = "baz";
|
||||||
|
};
|
||||||
|
expected = ''
|
||||||
|
key=value
|
||||||
|
other\=key=baz
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
testToINIEmpty = {
|
||||||
|
expr = generators.toINI {} {};
|
||||||
|
expected = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
testToINIEmptySection = {
|
||||||
|
expr = generators.toINI {} { foo = {}; bar = {}; };
|
||||||
|
expected = ''
|
||||||
|
[bar]
|
||||||
|
|
||||||
|
[foo]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
testToINIDefaultEscapes = {
|
||||||
|
expr = generators.toINI {} {
|
||||||
|
"no [ and ] allowed unescaped" = {
|
||||||
|
"and also no = in keys" = 42;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
expected = ''
|
||||||
|
[no \[ and \] allowed unescaped]
|
||||||
|
and also no \= in keys=42
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
testToINIDefaultFull = {
|
||||||
|
expr = generators.toINI {} {
|
||||||
|
"section 1" = {
|
||||||
|
attribute1 = 5;
|
||||||
|
x = "Me-se JarJar Binx";
|
||||||
|
};
|
||||||
|
"foo[]" = {
|
||||||
|
"he\\h=he" = "this is okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
expected = ''
|
||||||
|
[foo\[\]]
|
||||||
|
he\h\=he=this is okay
|
||||||
|
|
||||||
|
[section 1]
|
||||||
|
attribute1=5
|
||||||
|
x=Me-se JarJar Binx
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
/* right now only invocation check */
|
||||||
|
testToJSONSimple =
|
||||||
|
let val = {
|
||||||
|
foobar = [ "baz" 1 2 3 ];
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
expr = generators.toJSON {} val;
|
||||||
|
# trivial implementation
|
||||||
|
expected = builtins.toJSON val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* right now only invocation check */
|
||||||
|
testToYAMLSimple =
|
||||||
|
let val = {
|
||||||
|
list = [ { one = 1; } { two = 2; } ];
|
||||||
|
all = 42;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
expr = generators.toYAML {} val;
|
||||||
|
# trivial implementation
|
||||||
|
expected = builtins.toJSON val;
|
||||||
|
};
|
||||||
|
|
||||||
|
testToPretty = {
|
||||||
|
expr = mapAttrs (const (generators.toPretty {})) rec {
|
||||||
|
int = 42;
|
||||||
|
bool = true;
|
||||||
|
string = "fnord";
|
||||||
|
null_ = null;
|
||||||
|
function = x: x;
|
||||||
|
functionArgs = { arg ? 4, foo }: arg;
|
||||||
|
list = [ 3 4 function [ false ] ];
|
||||||
|
attrs = { foo = null; "foo bar" = "baz"; };
|
||||||
|
drv = derivation { name = "test"; system = builtins.currentSystem; };
|
||||||
|
};
|
||||||
|
expected = rec {
|
||||||
|
int = "42";
|
||||||
|
bool = "true";
|
||||||
|
string = "\"fnord\"";
|
||||||
|
null_ = "null";
|
||||||
|
function = "<λ>";
|
||||||
|
functionArgs = "<λ:{(arg),foo}>";
|
||||||
|
list = "[ 3 4 ${function} [ false ] ]";
|
||||||
|
attrs = "{ \"foo\" = null; \"foo bar\" = \"baz\"; }";
|
||||||
|
drv = "<δ>";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testToPrettyAllowPrettyValues = {
|
||||||
|
expr = generators.toPretty { allowPrettyValues = true; }
|
||||||
|
{ __pretty = v: "«" + v + "»"; val = "foo"; };
|
||||||
|
expected = "«foo»";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# MISC
|
||||||
|
|
||||||
|
testOverridableDelayableArgsTest = {
|
||||||
|
expr =
|
||||||
|
let res1 = defaultOverridableDelayableArgs id {};
|
||||||
|
res2 = defaultOverridableDelayableArgs id { a = 7; };
|
||||||
|
res3 = let x = defaultOverridableDelayableArgs id { a = 7; };
|
||||||
|
in (x.merge) { b = 10; };
|
||||||
|
res4 = let x = defaultOverridableDelayableArgs id { a = 7; };
|
||||||
|
in (x.merge) ( x: { b = 10; });
|
||||||
|
res5 = let x = defaultOverridableDelayableArgs id { a = 7; };
|
||||||
|
in (x.merge) ( x: { a = builtins.add x.a 3; });
|
||||||
|
res6 = let x = defaultOverridableDelayableArgs id { a = 7; mergeAttrBy = { a = builtins.add; }; };
|
||||||
|
y = x.merge {};
|
||||||
|
in (y.merge) { a = 10; };
|
||||||
|
|
||||||
|
resRem7 = res6.replace (a: removeAttrs a ["a"]);
|
||||||
|
|
||||||
|
resReplace6 = let x = defaultOverridableDelayableArgs id { a = 7; mergeAttrBy = { a = builtins.add; }; };
|
||||||
|
x2 = x.merge { a = 20; }; # now we have 27
|
||||||
|
in (x2.replace) { a = 10; }; # and override the value by 10
|
||||||
|
|
||||||
|
# fixed tests (delayed args): (when using them add some comments, please)
|
||||||
|
resFixed1 =
|
||||||
|
let x = defaultOverridableDelayableArgs id ( x: { a = 7; c = x.fixed.b; });
|
||||||
|
y = x.merge (x: { name = "name-${builtins.toString x.fixed.c}"; });
|
||||||
|
in (y.merge) { b = 10; };
|
||||||
|
strip = attrs: removeAttrs attrs ["merge" "replace"];
|
||||||
|
in all id
|
||||||
|
[ ((strip res1) == { })
|
||||||
|
((strip res2) == { a = 7; })
|
||||||
|
((strip res3) == { a = 7; b = 10; })
|
||||||
|
((strip res4) == { a = 7; b = 10; })
|
||||||
|
((strip res5) == { a = 10; })
|
||||||
|
((strip res6) == { a = 17; })
|
||||||
|
((strip resRem7) == {})
|
||||||
|
((strip resFixed1) == { a = 7; b = 10; c =10; name = "name-10"; })
|
||||||
|
];
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
+25
-33
@@ -1,40 +1,32 @@
|
|||||||
{ nixpkgs ? { outPath = (import ../.).cleanSource ../..; revCount = 1234; shortRev = "abcdef"; }
|
{ pkgs ? import ((import ../.).cleanSource ../..) {} }:
|
||||||
, # The platforms for which we build Nixpkgs.
|
|
||||||
supportedSystems ? [ builtins.currentSystem ]
|
|
||||||
, # Strip most of attributes when evaluating to spare memory usage
|
|
||||||
scrubJobs ? true
|
|
||||||
}:
|
|
||||||
|
|
||||||
with import ../../pkgs/top-level/release-lib.nix { inherit supportedSystems scrubJobs; };
|
pkgs.stdenv.mkDerivation {
|
||||||
with lib;
|
name = "nixpkgs-lib-tests";
|
||||||
|
buildInputs = [ pkgs.nix ];
|
||||||
|
NIX_PATH="nixpkgs=${pkgs.path}";
|
||||||
|
|
||||||
{
|
buildCommand = ''
|
||||||
systems = import ./systems.nix { inherit lib assertTrue; };
|
datadir="${pkgs.nix}/share"
|
||||||
|
export TEST_ROOT=$(pwd)/test-tmp
|
||||||
|
export NIX_BUILD_HOOK=
|
||||||
|
export NIX_CONF_DIR=$TEST_ROOT/etc
|
||||||
|
export NIX_DB_DIR=$TEST_ROOT/db
|
||||||
|
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
|
||||||
|
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
|
||||||
|
export NIX_MANIFESTS_DIR=$TEST_ROOT/var/nix/manifests
|
||||||
|
export NIX_STATE_DIR=$TEST_ROOT/var/nix
|
||||||
|
export NIX_STORE_DIR=$TEST_ROOT/store
|
||||||
|
export PAGER=cat
|
||||||
|
cacheDir=$TEST_ROOT/binary-cache
|
||||||
|
nix-store --init
|
||||||
|
|
||||||
moduleSystem = pkgs.stdenv.mkDerivation {
|
cd ${pkgs.path}/lib/tests
|
||||||
name = "nixpkgs-lib-tests";
|
./modules.sh
|
||||||
buildInputs = [ pkgs.nix ];
|
|
||||||
NIX_PATH="nixpkgs=${nixpkgs}";
|
|
||||||
|
|
||||||
buildCommand = ''
|
[[ "$(nix-instantiate --eval --strict misc.nix)" == "[ ]" ]]
|
||||||
datadir="${pkgs.nix}/share"
|
|
||||||
export TEST_ROOT=$(pwd)/test-tmp
|
|
||||||
export NIX_BUILD_HOOK=
|
|
||||||
export NIX_CONF_DIR=$TEST_ROOT/etc
|
|
||||||
export NIX_DB_DIR=$TEST_ROOT/db
|
|
||||||
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
|
|
||||||
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
|
|
||||||
export NIX_MANIFESTS_DIR=$TEST_ROOT/var/nix/manifests
|
|
||||||
export NIX_STATE_DIR=$TEST_ROOT/var/nix
|
|
||||||
export NIX_STORE_DIR=$TEST_ROOT/store
|
|
||||||
export PAGER=cat
|
|
||||||
cacheDir=$TEST_ROOT/binary-cache
|
|
||||||
nix-store --init
|
|
||||||
|
|
||||||
cd ${nixpkgs}/lib/tests
|
[[ "$(nix-instantiate --eval --strict systems.nix)" == "[ ]" ]]
|
||||||
./modules.sh
|
|
||||||
|
|
||||||
touch $out
|
touch $out
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,13 @@
|
|||||||
# calculating the lists anyway?". The answer is one can mindlessly update these
|
# calculating the lists anyway?". The answer is one can mindlessly update these
|
||||||
# tests as new platforms become supported, and then just give the diff a quick
|
# tests as new platforms become supported, and then just give the diff a quick
|
||||||
# sanity check before committing :).
|
# sanity check before committing :).
|
||||||
{ lib, assertTrue }:
|
let
|
||||||
|
lib = import ../default.nix;
|
||||||
with lib.systems.doubles;
|
mseteq = x: y: {
|
||||||
|
expr = lib.sort lib.lessThan x;
|
||||||
let mseteq = x: y: lib.sort lib.lessThan x == lib.sort lib.lessThan y; in
|
expected = lib.sort lib.lessThan y;
|
||||||
|
};
|
||||||
{
|
in with lib.systems.doubles; lib.runTests {
|
||||||
all = assertTrue (mseteq all (linux ++ darwin ++ cygwin ++ freebsd ++ openbsd ++ netbsd ++ illumos));
|
all = assertTrue (mseteq all (linux ++ darwin ++ cygwin ++ freebsd ++ openbsd ++ netbsd ++ illumos));
|
||||||
|
|
||||||
arm = assertTrue (mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv7l-linux" ]);
|
arm = assertTrue (mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv7l-linux" ]);
|
||||||
|
|||||||
+13
-78
@@ -1,3 +1,4 @@
|
|||||||
|
{ lib }:
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
/* The identity function
|
/* The identity function
|
||||||
@@ -38,87 +39,11 @@ rec {
|
|||||||
/* Merge two attribute sets shallowly, right side trumps left
|
/* Merge two attribute sets shallowly, right side trumps left
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
mergeAttrs { a = 1; b = 2; } // { b = 3; c = 4; }
|
mergeAttrs { a = 1; b = 2; } { b = 3; c = 4; }
|
||||||
=> { a = 1; b = 3; c = 4; }
|
=> { a = 1; b = 3; c = 4; }
|
||||||
*/
|
*/
|
||||||
mergeAttrs = x: y: x // y;
|
mergeAttrs = x: y: x // y;
|
||||||
|
|
||||||
|
|
||||||
# Compute the fixed point of the given function `f`, which is usually an
|
|
||||||
# attribute set that expects its final, non-recursive representation as an
|
|
||||||
# argument:
|
|
||||||
#
|
|
||||||
# f = self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; }
|
|
||||||
#
|
|
||||||
# Nix evaluates this recursion until all references to `self` have been
|
|
||||||
# resolved. At that point, the final result is returned and `f x = x` holds:
|
|
||||||
#
|
|
||||||
# nix-repl> fix f
|
|
||||||
# { bar = "bar"; foo = "foo"; foobar = "foobar"; }
|
|
||||||
#
|
|
||||||
# See https://en.wikipedia.org/wiki/Fixed-point_combinator for further
|
|
||||||
# details.
|
|
||||||
fix = f: let x = f x; in x;
|
|
||||||
|
|
||||||
# A variant of `fix` that records the original recursive attribute set in the
|
|
||||||
# result. This is useful in combination with the `extends` function to
|
|
||||||
# implement deep overriding. See pkgs/development/haskell-modules/default.nix
|
|
||||||
# for a concrete example.
|
|
||||||
fix' = f: let x = f x // { __unfix__ = f; }; in x;
|
|
||||||
|
|
||||||
# Modify the contents of an explicitly recursive attribute set in a way that
|
|
||||||
# honors `self`-references. This is accomplished with a function
|
|
||||||
#
|
|
||||||
# g = self: super: { foo = super.foo + " + "; }
|
|
||||||
#
|
|
||||||
# that has access to the unmodified input (`super`) as well as the final
|
|
||||||
# non-recursive representation of the attribute set (`self`). `extends`
|
|
||||||
# differs from the native `//` operator insofar as that it's applied *before*
|
|
||||||
# references to `self` are resolved:
|
|
||||||
#
|
|
||||||
# nix-repl> fix (extends g f)
|
|
||||||
# { bar = "bar"; foo = "foo + "; foobar = "foo + bar"; }
|
|
||||||
#
|
|
||||||
# The name of the function is inspired by object-oriented inheritance, i.e.
|
|
||||||
# think of it as an infix operator `g extends f` that mimics the syntax from
|
|
||||||
# Java. It may seem counter-intuitive to have the "base class" as the second
|
|
||||||
# argument, but it's nice this way if several uses of `extends` are cascaded.
|
|
||||||
extends = f: rattrs: self: let super = rattrs self; in super // f self super;
|
|
||||||
|
|
||||||
# Compose two extending functions of the type expected by 'extends'
|
|
||||||
# into one where changes made in the first are available in the
|
|
||||||
# 'super' of the second
|
|
||||||
composeExtensions =
|
|
||||||
f: g: self: super:
|
|
||||||
let fApplied = f self super;
|
|
||||||
super' = super // fApplied;
|
|
||||||
in fApplied // g self super';
|
|
||||||
|
|
||||||
# Create an overridable, recursive attribute set. For example:
|
|
||||||
#
|
|
||||||
# nix-repl> obj = makeExtensible (self: { })
|
|
||||||
#
|
|
||||||
# nix-repl> obj
|
|
||||||
# { __unfix__ = «lambda»; extend = «lambda»; }
|
|
||||||
#
|
|
||||||
# nix-repl> obj = obj.extend (self: super: { foo = "foo"; })
|
|
||||||
#
|
|
||||||
# nix-repl> obj
|
|
||||||
# { __unfix__ = «lambda»; extend = «lambda»; foo = "foo"; }
|
|
||||||
#
|
|
||||||
# nix-repl> obj = obj.extend (self: super: { foo = super.foo + " + "; bar = "bar"; foobar = self.foo + self.bar; })
|
|
||||||
#
|
|
||||||
# nix-repl> obj
|
|
||||||
# { __unfix__ = «lambda»; bar = "bar"; extend = «lambda»; foo = "foo + "; foobar = "foo + bar"; }
|
|
||||||
makeExtensible = makeExtensibleWithCustomName "extend";
|
|
||||||
|
|
||||||
# Same as `makeExtensible` but the name of the extending attribute is
|
|
||||||
# customized.
|
|
||||||
makeExtensibleWithCustomName = extenderName: rattrs:
|
|
||||||
fix' rattrs // {
|
|
||||||
${extenderName} = f: makeExtensibleWithCustomName extenderName (extends f rattrs);
|
|
||||||
};
|
|
||||||
|
|
||||||
# Flip the order of the arguments of a binary function.
|
# Flip the order of the arguments of a binary function.
|
||||||
flip = f: a: b: f b a;
|
flip = f: a: b: f b a;
|
||||||
|
|
||||||
@@ -131,7 +56,7 @@ rec {
|
|||||||
isInt add sub lessThan
|
isInt add sub lessThan
|
||||||
seq deepSeq genericClosure;
|
seq deepSeq genericClosure;
|
||||||
|
|
||||||
inherit (import ./strings.nix) fileContents;
|
inherit (lib.strings) fileContents;
|
||||||
|
|
||||||
# Return the Nixpkgs version number.
|
# Return the Nixpkgs version number.
|
||||||
nixpkgsVersion =
|
nixpkgsVersion =
|
||||||
@@ -146,6 +71,16 @@ rec {
|
|||||||
min = x: y: if x < y then x else y;
|
min = x: y: if x < y then x else y;
|
||||||
max = x: y: if x > y then x else y;
|
max = x: y: if x > y then x else y;
|
||||||
|
|
||||||
|
/* Integer modulus
|
||||||
|
|
||||||
|
Example:
|
||||||
|
mod 11 10
|
||||||
|
=> 1
|
||||||
|
mod 1 10
|
||||||
|
=> 1
|
||||||
|
*/
|
||||||
|
mod = base: int: base - (int * (builtins.div base int));
|
||||||
|
|
||||||
/* Reads a JSON file. */
|
/* Reads a JSON file. */
|
||||||
importJSON = path:
|
importJSON = path:
|
||||||
builtins.fromJSON (builtins.readFile path);
|
builtins.fromJSON (builtins.readFile path);
|
||||||
|
|||||||
+36
-36
@@ -1,15 +1,16 @@
|
|||||||
# Definitions related to run-time type checking. Used in particular
|
# Definitions related to run-time type checking. Used in particular
|
||||||
# to type-check NixOS configurations.
|
# to type-check NixOS configurations.
|
||||||
|
{ lib }:
|
||||||
|
with lib.lists;
|
||||||
|
with lib.attrsets;
|
||||||
|
with lib.options;
|
||||||
|
with lib.trivial;
|
||||||
|
with lib.strings;
|
||||||
|
let
|
||||||
|
|
||||||
with import ./lists.nix;
|
inherit (lib.modules) mergeDefinitions filterOverrides;
|
||||||
with import ./attrsets.nix;
|
outer_types =
|
||||||
with import ./options.nix;
|
|
||||||
with import ./trivial.nix;
|
|
||||||
with import ./strings.nix;
|
|
||||||
let inherit (import ./modules.nix) mergeDefinitions filterOverrides; in
|
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
isType = type: x: (x._type or "") == type;
|
isType = type: x: (x._type or "") == type;
|
||||||
|
|
||||||
setType = typeName: value: value // {
|
setType = typeName: value: value // {
|
||||||
@@ -92,8 +93,9 @@ rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# When adding new types don't forget to document them in
|
||||||
|
# nixos/doc/manual/development/option-types.xml!
|
||||||
types = rec {
|
types = rec {
|
||||||
|
|
||||||
unspecified = mkOptionType {
|
unspecified = mkOptionType {
|
||||||
name = "unspecified";
|
name = "unspecified";
|
||||||
};
|
};
|
||||||
@@ -177,9 +179,9 @@ rec {
|
|||||||
description = "list of ${elemType.description}s";
|
description = "list of ${elemType.description}s";
|
||||||
check = isList;
|
check = isList;
|
||||||
merge = loc: defs:
|
merge = loc: defs:
|
||||||
map (x: x.value) (filter (x: x ? value) (concatLists (imap (n: def:
|
map (x: x.value) (filter (x: x ? value) (concatLists (imap1 (n: def:
|
||||||
if isList def.value then
|
if isList def.value then
|
||||||
imap (m: def':
|
imap1 (m: def':
|
||||||
(mergeDefinitions
|
(mergeDefinitions
|
||||||
(loc ++ ["[definition ${toString n}-entry ${toString m}]"])
|
(loc ++ ["[definition ${toString n}-entry ${toString m}]"])
|
||||||
elemType
|
elemType
|
||||||
@@ -218,7 +220,7 @@ rec {
|
|||||||
if isList def.value then
|
if isList def.value then
|
||||||
{ inherit (def) file;
|
{ inherit (def) file;
|
||||||
value = listToAttrs (
|
value = listToAttrs (
|
||||||
imap (elemIdx: elem:
|
imap1 (elemIdx: elem:
|
||||||
{ name = elem.name or "unnamed-${toString defIdx}.${toString elemIdx}";
|
{ name = elem.name or "unnamed-${toString defIdx}.${toString elemIdx}";
|
||||||
value = elem;
|
value = elem;
|
||||||
}) def.value);
|
}) def.value);
|
||||||
@@ -231,32 +233,14 @@ rec {
|
|||||||
name = "loaOf";
|
name = "loaOf";
|
||||||
description = "list or attribute set of ${elemType.description}s";
|
description = "list or attribute set of ${elemType.description}s";
|
||||||
check = x: isList x || isAttrs x;
|
check = x: isList x || isAttrs x;
|
||||||
merge = loc: defs: attrOnly.merge loc (imap convertIfList defs);
|
merge = loc: defs: attrOnly.merge loc (imap1 convertIfList defs);
|
||||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name?>"]);
|
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name?>"]);
|
||||||
getSubModules = elemType.getSubModules;
|
getSubModules = elemType.getSubModules;
|
||||||
substSubModules = m: loaOf (elemType.substSubModules m);
|
substSubModules = m: loaOf (elemType.substSubModules m);
|
||||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||||
};
|
};
|
||||||
|
|
||||||
# List or element of ...
|
# Value of given type but with no merging (i.e. `uniq list`s are not concatenated).
|
||||||
loeOf = elemType: mkOptionType rec {
|
|
||||||
name = "loeOf";
|
|
||||||
description = "element or list of ${elemType.description}s";
|
|
||||||
check = x: isList x || elemType.check x;
|
|
||||||
merge = loc: defs:
|
|
||||||
let
|
|
||||||
defs' = filterOverrides defs;
|
|
||||||
res = (head defs').value;
|
|
||||||
in
|
|
||||||
if isList res then concatLists (getValues defs')
|
|
||||||
else if lessThan 1 (length defs') then
|
|
||||||
throw "The option `${showOption loc}' is defined multiple times, in ${showFiles (getFiles defs)}."
|
|
||||||
else if !isString res then
|
|
||||||
throw "The option `${showOption loc}' does not have a string value, in ${showFiles (getFiles defs)}."
|
|
||||||
else res;
|
|
||||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
|
||||||
};
|
|
||||||
|
|
||||||
uniq = elemType: mkOptionType rec {
|
uniq = elemType: mkOptionType rec {
|
||||||
name = "uniq";
|
name = "uniq";
|
||||||
inherit (elemType) description check;
|
inherit (elemType) description check;
|
||||||
@@ -267,6 +251,7 @@ rec {
|
|||||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Null or value of ...
|
||||||
nullOr = elemType: mkOptionType rec {
|
nullOr = elemType: mkOptionType rec {
|
||||||
name = "nullOr";
|
name = "nullOr";
|
||||||
description = "null or ${elemType.description}";
|
description = "null or ${elemType.description}";
|
||||||
@@ -283,10 +268,11 @@ rec {
|
|||||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# A submodule (like typed attribute set). See NixOS manual.
|
||||||
submodule = opts:
|
submodule = opts:
|
||||||
let
|
let
|
||||||
opts' = toList opts;
|
opts' = toList opts;
|
||||||
inherit (import ./modules.nix) evalModules;
|
inherit (lib.modules) evalModules;
|
||||||
in
|
in
|
||||||
mkOptionType rec {
|
mkOptionType rec {
|
||||||
name = "submodule";
|
name = "submodule";
|
||||||
@@ -302,8 +288,17 @@ rec {
|
|||||||
}).config;
|
}).config;
|
||||||
getSubOptions = prefix: (evalModules
|
getSubOptions = prefix: (evalModules
|
||||||
{ modules = opts'; inherit prefix;
|
{ modules = opts'; inherit prefix;
|
||||||
# FIXME: hack to get shit to evaluate.
|
# This is a work-around due to the fact that some sub-modules,
|
||||||
args = { name = ""; }; }).options;
|
# such as the one included in an attribute set, expects a "args"
|
||||||
|
# attribute to be given to the sub-module. As the option
|
||||||
|
# evaluation does not have any specific attribute name, we
|
||||||
|
# provide a default one for the documentation.
|
||||||
|
#
|
||||||
|
# This is mandatory as some option declaration might use the
|
||||||
|
# "name" attribute given as argument of the submodule and use it
|
||||||
|
# as the default of option declarations.
|
||||||
|
args.name = "<name>";
|
||||||
|
}).options;
|
||||||
getSubModules = opts';
|
getSubModules = opts';
|
||||||
substSubModules = m: submodule m;
|
substSubModules = m: submodule m;
|
||||||
functor = (defaultFunctor name) // {
|
functor = (defaultFunctor name) // {
|
||||||
@@ -314,6 +309,7 @@ rec {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# A value from a set of allowed ones.
|
||||||
enum = values:
|
enum = values:
|
||||||
let
|
let
|
||||||
show = v:
|
show = v:
|
||||||
@@ -329,6 +325,7 @@ rec {
|
|||||||
functor = (defaultFunctor name) // { payload = values; binOp = a: b: unique (a ++ b); };
|
functor = (defaultFunctor name) // { payload = values; binOp = a: b: unique (a ++ b); };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Either value of type `t1` or `t2`.
|
||||||
either = t1: t2: mkOptionType rec {
|
either = t1: t2: mkOptionType rec {
|
||||||
name = "either";
|
name = "either";
|
||||||
description = "${t1.description} or ${t2.description}";
|
description = "${t1.description} or ${t2.description}";
|
||||||
@@ -352,6 +349,8 @@ rec {
|
|||||||
functor = (defaultFunctor name) // { wrapped = [ t1 t2 ]; };
|
functor = (defaultFunctor name) // { wrapped = [ t1 t2 ]; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Either value of type `finalType` or `coercedType`, the latter is
|
||||||
|
# converted to `finalType` using `coerceFunc`.
|
||||||
coercedTo = coercedType: coerceFunc: finalType:
|
coercedTo = coercedType: coerceFunc: finalType:
|
||||||
assert coercedType.getSubModules == null;
|
assert coercedType.getSubModules == null;
|
||||||
mkOptionType rec {
|
mkOptionType rec {
|
||||||
@@ -386,5 +385,6 @@ rec {
|
|||||||
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };
|
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
}
|
in outer_types // outer_types.types
|
||||||
|
|||||||
@@ -2,26 +2,24 @@
|
|||||||
|
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
GNOME_FTP="ftp.gnome.org/pub/GNOME/sources"
|
GNOME_FTP=ftp.gnome.org/pub/GNOME/sources
|
||||||
|
|
||||||
# projects that don't follow the GNOME major versioning, or that we don't want to
|
# projects that don't follow the GNOME major versioning, or that we don't want to
|
||||||
# programmatically update
|
# programmatically update
|
||||||
NO_GNOME_MAJOR="gtkhtml gdm"
|
NO_GNOME_MAJOR="ghex gtkhtml gdm gucharmap"
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "Usage: $0 gnome_dir <show project>|<update project>|<update-all> [major.minor]" >&2
|
echo "Usage: $0 <show project>|<update project>|<update-all> [major.minor]" >&2
|
||||||
echo "gnome_dir is for example pkgs/desktops/gnome-3/3.18" >&2
|
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ "$#" -lt 2 ]; then
|
if [ "$#" -lt 1 ]; then
|
||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
|
|
||||||
GNOME_TOP="$1"
|
GNOME_TOP=pkgs/desktops/gnome-3
|
||||||
shift
|
|
||||||
|
|
||||||
action="$1"
|
action=$1
|
||||||
|
|
||||||
# curl -l ftp://... doesn't work from my office in HSE, and I don't want to have
|
# curl -l ftp://... doesn't work from my office in HSE, and I don't want to have
|
||||||
# any conversations with sysadmin. Somehow lftp works.
|
# any conversations with sysadmin. Somehow lftp works.
|
||||||
@@ -36,18 +34,18 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
find_project() {
|
find_project() {
|
||||||
exec find "$GNOME_TOP" -mindepth 2 -maxdepth 2 -type d $@
|
exec find "$GNOME_TOP" -mindepth 2 -maxdepth 2 -type d "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
show_project() {
|
show_project() {
|
||||||
local project="$1"
|
local project=$1
|
||||||
local majorVersion="$2"
|
local majorVersion=$2
|
||||||
local version=""
|
local version=
|
||||||
|
|
||||||
if [ -z "$majorVersion" ]; then
|
if [ -z "$majorVersion" ]; then
|
||||||
echo "Looking for available versions..." >&2
|
echo "Looking for available versions..." >&2
|
||||||
local available_baseversions=( `ls_ftp ftp://${GNOME_FTP}/${project} | grep '[0-9]\.[0-9]' | sort -t. -k1,1n -k 2,2n` )
|
local available_baseversions=$(ls_ftp ftp://${GNOME_FTP}/${project} | grep '[0-9]\.[0-9]' | sort -t. -k1,1n -k 2,2n)
|
||||||
if [ "$?" -ne "0" ]; then
|
if [ "$?" -ne 0 ]; then
|
||||||
echo "Project $project not found" >&2
|
echo "Project $project not found" >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -59,11 +57,11 @@ show_project() {
|
|||||||
|
|
||||||
if echo "$majorVersion" | grep -q "[0-9]\+\.[0-9]\+\.[0-9]\+"; then
|
if echo "$majorVersion" | grep -q "[0-9]\+\.[0-9]\+\.[0-9]\+"; then
|
||||||
# not a major version
|
# not a major version
|
||||||
version="$majorVersion"
|
version=$majorVersion
|
||||||
majorVersion=$(echo "$majorVersion" | cut -d '.' -f 1,2)
|
majorVersion=$(echo "$majorVersion" | cut -d '.' -f 1,2)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local FTPDIR="${GNOME_FTP}/${project}/${majorVersion}"
|
local FTPDIR=${GNOME_FTP}/${project}/${majorVersion}
|
||||||
|
|
||||||
#version=`curl -l ${FTPDIR}/ 2>/dev/null | grep LATEST-IS | sed -e s/LATEST-IS-//`
|
#version=`curl -l ${FTPDIR}/ 2>/dev/null | grep LATEST-IS | sed -e s/LATEST-IS-//`
|
||||||
# gnome's LATEST-IS is broken. Do not trust it.
|
# gnome's LATEST-IS is broken. Do not trust it.
|
||||||
@@ -92,7 +90,7 @@ show_project() {
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
echo "Found versions ${!versions[@]}" >&2
|
echo "Found versions ${!versions[@]}" >&2
|
||||||
version=`echo ${!versions[@]} | sed -e 's/ /\n/g' | sort -t. -k1,1n -k 2,2n -k 3,3n | tail -n1`
|
version=$(echo ${!versions[@]} | sed -e 's/ /\n/g' | sort -t. -k1,1n -k 2,2n -k 3,3n | tail -n1)
|
||||||
if [ -z "$version" ]; then
|
if [ -z "$version" ]; then
|
||||||
echo "No version available for major $majorVersion" >&2
|
echo "No version available for major $majorVersion" >&2
|
||||||
return 1
|
return 1
|
||||||
@@ -103,7 +101,7 @@ show_project() {
|
|||||||
|
|
||||||
local name=${project}-${version}
|
local name=${project}-${version}
|
||||||
echo "Fetching .sha256 file" >&2
|
echo "Fetching .sha256 file" >&2
|
||||||
local sha256out=$(curl -s -f http://${FTPDIR}/${name}.sha256sum)
|
local sha256out=$(curl -s -f http://"${FTPDIR}"/"${name}".sha256sum)
|
||||||
|
|
||||||
if [ "$?" -ne "0" ]; then
|
if [ "$?" -ne "0" ]; then
|
||||||
echo "Version not found" >&2
|
echo "Version not found" >&2
|
||||||
@@ -136,8 +134,8 @@ fetchurl: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update_project() {
|
update_project() {
|
||||||
local project="$1"
|
local project=$1
|
||||||
local majorVersion="$2"
|
local majorVersion=$2
|
||||||
|
|
||||||
# find project in nixpkgs tree
|
# find project in nixpkgs tree
|
||||||
projectPath=$(find_project -name "$project" -print)
|
projectPath=$(find_project -name "$project" -print)
|
||||||
@@ -150,14 +148,14 @@ update_project() {
|
|||||||
|
|
||||||
if [ "$?" -eq "0" ]; then
|
if [ "$?" -eq "0" ]; then
|
||||||
echo "Updating $projectPath/src.nix" >&2
|
echo "Updating $projectPath/src.nix" >&2
|
||||||
echo -e "$src" > "$projectPath/src.nix"
|
echo -e "$src" > "$projectPath"/src.nix
|
||||||
fi
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ "$action" == "update-all" ]; then
|
if [ "$action" = "update-all" ]; then
|
||||||
majorVersion="$2"
|
majorVersion=$2
|
||||||
if [ -z "$majorVersion" ]; then
|
if [ -z "$majorVersion" ]; then
|
||||||
echo "No major version specified" >&2
|
echo "No major version specified" >&2
|
||||||
usage
|
usage
|
||||||
@@ -170,23 +168,23 @@ if [ "$action" == "update-all" ]; then
|
|||||||
echo "Skipping $project"
|
echo "Skipping $project"
|
||||||
else
|
else
|
||||||
echo "= Updating $project to $majorVersion" >&2
|
echo "= Updating $project to $majorVersion" >&2
|
||||||
update_project $project $majorVersion
|
update_project "$project" "$majorVersion"
|
||||||
echo >&2
|
echo >&2
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
project="$2"
|
project=$2
|
||||||
majorVersion="$3"
|
majorVersion=$3
|
||||||
|
|
||||||
if [ -z "$project" ]; then
|
if [ -z "$project" ]; then
|
||||||
echo "No project specified, exiting" >&2
|
echo "No project specified, exiting" >&2
|
||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$action" == "show" ]; then
|
if [ "$action" = show ]; then
|
||||||
show_project $project $majorVersion
|
show_project "$project" "$majorVersion"
|
||||||
elif [ "$action" == "update" ]; then
|
elif [ "$action" = update ]; then
|
||||||
update_project $project $majorVersion
|
update_project "$project" "$majorVersion"
|
||||||
else
|
else
|
||||||
echo "Unknown action $action" >&2
|
echo "Unknown action $action" >&2
|
||||||
usage
|
usage
|
||||||
|
|||||||
@@ -13,10 +13,8 @@ from pyquery import PyQuery as pq
|
|||||||
|
|
||||||
|
|
||||||
maintainers_json = subprocess.check_output([
|
maintainers_json = subprocess.check_output([
|
||||||
'nix-instantiate',
|
'nix-instantiate', '-E', 'import ./lib/maintainers.nix {}', '--eval', '--json'
|
||||||
'lib/maintainers.nix',
|
])
|
||||||
'--eval',
|
|
||||||
'--json'])
|
|
||||||
maintainers = json.loads(maintainers_json)
|
maintainers = json.loads(maintainers_json)
|
||||||
MAINTAINERS = {v: k for k, v in maintainers.iteritems()}
|
MAINTAINERS = {v: k for k, v in maintainers.iteritems()}
|
||||||
|
|
||||||
@@ -31,25 +29,28 @@ EVAL_FILE = {
|
|||||||
|
|
||||||
|
|
||||||
def get_maintainers(attr_name):
|
def get_maintainers(attr_name):
|
||||||
nixname = attr_name.split('.')
|
try:
|
||||||
meta_json = subprocess.check_output([
|
nixname = attr_name.split('.')
|
||||||
'nix-instantiate',
|
meta_json = subprocess.check_output([
|
||||||
'--eval',
|
'nix-instantiate',
|
||||||
'--strict',
|
'--eval',
|
||||||
'-A',
|
'--strict',
|
||||||
'.'.join(nixname[1:]) + '.meta',
|
'-A',
|
||||||
EVAL_FILE[nixname[0]],
|
'.'.join(nixname[1:]) + '.meta',
|
||||||
'--json'])
|
EVAL_FILE[nixname[0]],
|
||||||
meta = json.loads(meta_json)
|
'--json'])
|
||||||
if meta.get('maintainers'):
|
meta = json.loads(meta_json)
|
||||||
return [MAINTAINERS[name] for name in meta['maintainers'] if MAINTAINERS.get(name)]
|
if meta.get('maintainers'):
|
||||||
|
return [MAINTAINERS[name] for name in meta['maintainers'] if MAINTAINERS.get(name)]
|
||||||
|
except:
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@click.option(
|
@click.option(
|
||||||
'--jobset',
|
'--jobset',
|
||||||
default="nixos/release-17.03",
|
default="nixos/release-17.09",
|
||||||
help='Hydra project like nixos/release-17.03')
|
help='Hydra project like nixos/release-17.09')
|
||||||
def cli(jobset):
|
def cli(jobset):
|
||||||
"""
|
"""
|
||||||
Given a Hydra project, inspect latest evaluation
|
Given a Hydra project, inspect latest evaluation
|
||||||
|
|||||||
@@ -1,260 +1,115 @@
|
|||||||
#!/bin/sh
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
usage () {
|
if [ "$#" != 1 ] && [ "$#" != 2 ]; then
|
||||||
echo 1>&2 "
|
cat <<-EOF
|
||||||
usage:
|
Usage: $0 commit-spec [commit-spec]
|
||||||
$0
|
You need to be in a git-controlled nixpkgs tree.
|
||||||
[--git commit..commit | --git commit]
|
The current state of the tree will be used if the second commit is missing.
|
||||||
[--svn rev:rev | --svn rev]
|
EOF
|
||||||
[--path path[:path]*]
|
exit 1
|
||||||
[--help]
|
|
||||||
|
|
||||||
This program is used to investigate how any changes inside your nixpkgs
|
|
||||||
repository may hurt. With these kind of information you may choose wisely
|
|
||||||
where you should commit your changes.
|
|
||||||
|
|
||||||
This program adapts it-self to your versionning system to avoid too much
|
|
||||||
effort on your Internet bandwidth. If you need to check more than one
|
|
||||||
commits / revisions, you may use the following commands:
|
|
||||||
|
|
||||||
--git remotes/trunk..master
|
|
||||||
--svn 17670:17677
|
|
||||||
|
|
||||||
Check the differences between each commit separating the first and the
|
|
||||||
last commit.
|
|
||||||
|
|
||||||
--path /etc/nixos/nixpkgs:/tmp/nixpkgs_1:/tmp/nixpkgs_2
|
|
||||||
|
|
||||||
Check the differences between multiple directories containing different
|
|
||||||
versions of nixpkgs.
|
|
||||||
|
|
||||||
All these options exist with one commit / revision argument. Such options
|
|
||||||
are used to compare your \$NIXPKGS path with the specified version.
|
|
||||||
|
|
||||||
If you omit to mention any other commit / revision, then your \$NIXPKGS path
|
|
||||||
is compared with its last update. This command is useful to test code from
|
|
||||||
a dirty repository.
|
|
||||||
|
|
||||||
"
|
|
||||||
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#####################
|
|
||||||
# Process Arguments #
|
|
||||||
#####################
|
|
||||||
|
|
||||||
: ${NIXPKGS=/etc/nixos/nixpkgs/}
|
|
||||||
|
|
||||||
vcs=""
|
|
||||||
gitCommits=""
|
|
||||||
svnRevisions=""
|
|
||||||
pathLocations=""
|
|
||||||
verbose=false
|
|
||||||
|
|
||||||
argfun=""
|
|
||||||
for arg; do
|
|
||||||
if test -z "$argfun"; then
|
|
||||||
case $arg in
|
|
||||||
--git) vcs="git"; argfun="set_gitCommits";;
|
|
||||||
--svn) vcs="svn"; argfun="set_svnRevisions";;
|
|
||||||
--path) vcs="path"; argfun="set_pathLocations";;
|
|
||||||
--verbose) verbose=true;;
|
|
||||||
--help) usage;;
|
|
||||||
*) usage;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
case $argfun in
|
|
||||||
set_*)
|
|
||||||
var=$(echo $argfun | sed 's,^set_,,')
|
|
||||||
eval $var=$arg
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
argfun=""
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if $verbose; then
|
|
||||||
set -x
|
|
||||||
else
|
|
||||||
set +x
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
############################
|
# A slightly hacky way to get the config.
|
||||||
# Find the repository type #
|
parallel="$(echo 'config.rebuild-amount.parallel or false' | nix-repl . 2>/dev/null \
|
||||||
############################
|
| grep -v '^\(nix-repl.*\)\?$' | tail -n 1 || true)"
|
||||||
|
|
||||||
if test -z "$vcs"; then
|
echo "Estimating rebuild amount by counting changed Hydra jobs."
|
||||||
if test -x "$NIXPKGS/.git"; then
|
|
||||||
if git --git-dir="$NIXPKGS/.git" branch > /dev/null 2>&1; then
|
|
||||||
vcs="git"
|
|
||||||
gitCommits=$(git --git-dir="$NIXPKGS/.git" log -n 1 --pretty=format:%H 2> /dev/null)
|
|
||||||
fi
|
|
||||||
elif test -x "$NIXPKGS/.svn"; then
|
|
||||||
cd "$NIXPKGS"
|
|
||||||
if svn info > /dev/null 2>&1; then
|
|
||||||
vcs="svn";
|
|
||||||
svnRevisions=$(svn info | sed -n 's,Revision: ,,p')
|
|
||||||
fi
|
|
||||||
cd -
|
|
||||||
else
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
###############################
|
toRemove=()
|
||||||
# Define a storage directory. #
|
|
||||||
###############################
|
|
||||||
|
|
||||||
pkgListDir=""
|
cleanup() {
|
||||||
exitCode=1
|
rm -rf "${toRemove[@]}"
|
||||||
cleanup(){
|
|
||||||
test -e "$pkgListDir" && rm -rf "$pkgListDir"
|
|
||||||
exit $exitCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trap cleanup EXIT SIGINT SIGQUIT ERR
|
trap cleanup EXIT SIGINT SIGQUIT ERR
|
||||||
|
|
||||||
pkgListDir=$(mktemp --tmpdir -d rebuild-amount-XXXXXXXX)
|
MKTEMP='mktemp --tmpdir nix-rebuild-amount-XXXXXXXX'
|
||||||
vcsDir="$pkgListDir/.vcs"
|
|
||||||
|
|
||||||
###########################
|
nixexpr() {
|
||||||
# Versionning for Dummies #
|
cat <<-EONIX
|
||||||
###########################
|
let
|
||||||
|
lib = import $1/lib;
|
||||||
|
hydraJobs = import $1/pkgs/top-level/release.nix
|
||||||
|
# Compromise: accuracy vs. resources needed for evaluation.
|
||||||
|
{ supportedSystems = cfg.systems or [ "x86_64-linux" "x86_64-darwin" ]; };
|
||||||
|
cfg = (import $1 {}).config.rebuild-amount or {};
|
||||||
|
|
||||||
path_init() {
|
recurseIntoAttrs = attrs: attrs // { recurseForDerivations = true; };
|
||||||
if test "${pathLocations#*:}" = "$pathLocations"; then
|
|
||||||
pathLocations="$NIXPKGS:$pathLocations"
|
# hydraJobs leaves recurseForDerivations as empty attrmaps;
|
||||||
fi
|
# that would break nix-env and we also need to recurse everywhere.
|
||||||
pathLocations="${pathLocations}:"
|
tweak = lib.mapAttrs
|
||||||
|
(name: val:
|
||||||
|
if name == "recurseForDerivations" then true
|
||||||
|
else if lib.isAttrs val && val.type or null != "derivation"
|
||||||
|
then recurseIntoAttrs (tweak val)
|
||||||
|
else val
|
||||||
|
);
|
||||||
|
|
||||||
|
# Some of these contain explicit references to platform(s) we want to avoid;
|
||||||
|
# some even (transitively) depend on ~/.nixpkgs/config.nix (!)
|
||||||
|
blacklist = [
|
||||||
|
"tarball" "metrics" "manual"
|
||||||
|
"darwin-tested" "unstable" "stdenvBootstrapTools"
|
||||||
|
"moduleSystem" "lib-tests" # these just confuse the output
|
||||||
|
];
|
||||||
|
|
||||||
|
in
|
||||||
|
tweak (builtins.removeAttrs hydraJobs blacklist)
|
||||||
|
EONIX
|
||||||
}
|
}
|
||||||
|
|
||||||
path_getNext() {
|
# Output packages in tree $2 that weren't in $1.
|
||||||
pathLoc="${pathLocations%%:*}"
|
# Changing the output hash or name is taken as a change.
|
||||||
pathLocations="${pathLocations#*:}"
|
# Extra nix-env parameters can be in $3
|
||||||
|
newPkgs() {
|
||||||
|
# We use files instead of pipes, as running multiple nix-env processes
|
||||||
|
# could eat too much memory for a standard 4GiB machine.
|
||||||
|
local -a list
|
||||||
|
for i in 1 2; do
|
||||||
|
local l="$($MKTEMP)"
|
||||||
|
list[$i]="$l"
|
||||||
|
toRemove+=("$l")
|
||||||
|
|
||||||
|
local expr="$($MKTEMP)"
|
||||||
|
toRemove+=("$expr")
|
||||||
|
nixexpr "${!i}" > "$expr"
|
||||||
|
|
||||||
|
nix-env -f "$expr" -qaP --no-name --out-path --show-trace $3 \
|
||||||
|
| sort > "${list[$i]}" &
|
||||||
|
|
||||||
|
if [ "$parallel" != "true" ]; then
|
||||||
|
wait
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
wait
|
||||||
|
comm -13 "${list[@]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
path_setPath() {
|
# Prepare nixpkgs trees.
|
||||||
path="$pathLoc"
|
declare -a tree
|
||||||
}
|
for i in 1 2; do
|
||||||
|
if [ -n "${!i}" ]; then # use the given commit
|
||||||
|
dir="$($MKTEMP -d)"
|
||||||
|
tree[$i]="$dir"
|
||||||
|
toRemove+=("$dir")
|
||||||
|
|
||||||
path_setName() {
|
git clone --shared --no-checkout --quiet . "${tree[$i]}"
|
||||||
name=$(echo "$pathLoc" | tr '/' '_')
|
(cd "${tree[$i]}" && git checkout --quiet "${!i}")
|
||||||
}
|
else #use the current tree
|
||||||
|
tree[$i]="$(pwd)"
|
||||||
################
|
fi
|
||||||
# Git Commands #
|
|
||||||
################
|
|
||||||
|
|
||||||
git_init() {
|
|
||||||
git clone "$NIXPKGS/.git" "$vcsDir" > /dev/null 2>&1
|
|
||||||
if echo "gitCommits" | grep -c "\.\." > /dev/null 2>&1; then
|
|
||||||
gitCommits=$(git --git-dir="$vcsDir/.git" log --reverse --pretty=format:%H $gitCommits 2> /dev/null)
|
|
||||||
else
|
|
||||||
pathLocations="$vcsDir:$NIXPKGS"
|
|
||||||
vcs="path"
|
|
||||||
path_init
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
git_getNext() {
|
|
||||||
git --git-dir="$vcsDir/.git" checkout $(echo "$gitCommits" | head -n 1) > /dev/null 2>&1
|
|
||||||
gitCommits=$(echo "$gitCommits" | sed '1 d')
|
|
||||||
}
|
|
||||||
|
|
||||||
git_setPath() {
|
|
||||||
path="$vcsDir"
|
|
||||||
}
|
|
||||||
|
|
||||||
git_setName() {
|
|
||||||
name=$(git --git-dir="$vcsDir/.git" log -n 1 --pretty=format:%H 2> /dev/null)
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################
|
|
||||||
# Subversion Commands #
|
|
||||||
#######################
|
|
||||||
|
|
||||||
svn_init() {
|
|
||||||
cp -r "$NIXPKGS" "$vcsDir" > /dev/null 2>&1
|
|
||||||
if echo "svnRevisions" | grep -c ":" > /dev/null 2>&1; then
|
|
||||||
svnRevisions=$(seq ${svnRevisions%:*} ${svnRevisions#*:})
|
|
||||||
else
|
|
||||||
pathLocations="$vcsDir:$NIXPKGS"
|
|
||||||
vcs="path"
|
|
||||||
path_init
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
svn_getNext() {
|
|
||||||
cd "$vcsDir"
|
|
||||||
svn checkout $(echo "$svnRevisions" | head -n 1) > /dev/null 2>&1
|
|
||||||
cd -
|
|
||||||
svnRevisions=$(echo "$svnRevisions" | sed '1 d')
|
|
||||||
}
|
|
||||||
|
|
||||||
svn_setPath() {
|
|
||||||
path="$vcsDir"
|
|
||||||
}
|
|
||||||
|
|
||||||
svn_setName() {
|
|
||||||
name=$(svn info 2> /dev/null | sed -n 's,Revision: ,,p')
|
|
||||||
}
|
|
||||||
|
|
||||||
####################
|
|
||||||
# Logical Commands #
|
|
||||||
####################
|
|
||||||
|
|
||||||
init () { ${vcs}_init; }
|
|
||||||
getNext () { ${vcs}_getNext; }
|
|
||||||
setPath () { ${vcs}_setPath; }
|
|
||||||
setName () { ${vcs}_setName; }
|
|
||||||
|
|
||||||
|
|
||||||
#####################
|
|
||||||
# Check for Rebuild #
|
|
||||||
#####################
|
|
||||||
|
|
||||||
# Generate the list of all derivations that could be build from a nixpkgs
|
|
||||||
# respository. This list of derivation hashes is compared with previous
|
|
||||||
# lists and a brief summary is produced on the output.
|
|
||||||
|
|
||||||
compareNames () {
|
|
||||||
nb=$(diff -y --suppress-common-lines --speed-large-files "$pkgListDir/$1.drvs" "$pkgListDir/$2.drvs" 2> /dev/null | wc -l)
|
|
||||||
echo "$1 -> $2: $nb"
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "Please wait, this may take some minutes ..."
|
|
||||||
|
|
||||||
init
|
|
||||||
first=""
|
|
||||||
oldPrev=""
|
|
||||||
|
|
||||||
prev=""
|
|
||||||
curr=""
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
getNext
|
|
||||||
setPath # set path=...
|
|
||||||
setName # set name=...
|
|
||||||
curr="$name"
|
|
||||||
|
|
||||||
test -z "$curr" && break || true
|
|
||||||
|
|
||||||
nix-instantiate "$path" > "$pkgListDir/$curr.drvs" > /dev/null 2>&1 || true
|
|
||||||
|
|
||||||
if test -n "$prev"; then
|
|
||||||
compareNames "$prev" "$curr"
|
|
||||||
else
|
|
||||||
echo "Number of package to rebuild:"
|
|
||||||
first="$curr"
|
|
||||||
fi
|
|
||||||
oldPrev="$prev"
|
|
||||||
prev="$curr"
|
|
||||||
done
|
done
|
||||||
|
|
||||||
if test "$first" != "$oldPrev"; then
|
newlist="$($MKTEMP)"
|
||||||
echo "Number of package to rebuild (first -> last):"
|
toRemove+=("$newlist")
|
||||||
compareNames "$first" "$curr"
|
# Notes:
|
||||||
fi
|
# - the evaluation is done on x86_64-linux, like on Hydra.
|
||||||
|
# - using $newlist file so that newPkgs() isn't in a sub-shell (because of toRemove)
|
||||||
|
newPkgs "${tree[1]}" "${tree[2]}" '--argstr system "x86_64-linux"' > "$newlist"
|
||||||
|
|
||||||
|
# Hacky: keep only the last word of each attribute path and sort.
|
||||||
|
sed -n 's/\([^. ]*\.\)*\([^. ]*\) .*$/\2/p' < "$newlist" \
|
||||||
|
| sort | uniq -c
|
||||||
|
|
||||||
exitCode=0
|
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ while test -n "$1"; do
|
|||||||
nox)
|
nox)
|
||||||
echo "=== Fetching Nox from binary cache"
|
echo "=== Fetching Nox from binary cache"
|
||||||
|
|
||||||
# build nox silently so it's not in the log
|
# build nox (+ a basic nix-shell env) silently so it's not in the log
|
||||||
nix-build "<nixpkgs>" -A nox -A stdenv
|
nix-shell -p nox stdenv --command true
|
||||||
;;
|
;;
|
||||||
|
|
||||||
pr)
|
pr)
|
||||||
|
|||||||
Executable
+243
@@ -0,0 +1,243 @@
|
|||||||
|
#! /usr/bin/env nix-shell
|
||||||
|
#! nix-shell -i python3 -p 'python3.withPackages(ps: with ps; [ requests toolz ])'
|
||||||
|
|
||||||
|
"""
|
||||||
|
Update a Python package expression by passing in the `.nix` file, or the directory containing it.
|
||||||
|
You can pass in multiple files or paths.
|
||||||
|
|
||||||
|
You'll likely want to use
|
||||||
|
``
|
||||||
|
$ ./update-python-libraries ../../pkgs/development/python-modules/*
|
||||||
|
``
|
||||||
|
to update all libraries in that folder.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import requests
|
||||||
|
import toolz
|
||||||
|
|
||||||
|
INDEX = "https://pypi.io/pypi"
|
||||||
|
"""url of PyPI"""
|
||||||
|
|
||||||
|
EXTENSIONS = ['tar.gz', 'tar.bz2', 'tar', 'zip', '.whl']
|
||||||
|
"""Permitted file extensions. These are evaluated from left to right and the first occurance is returned."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_values(attribute, text):
|
||||||
|
"""Match attribute in text and return all matches.
|
||||||
|
|
||||||
|
:returns: List of matches.
|
||||||
|
"""
|
||||||
|
regex = '{}\s+=\s+"(.*)";'.format(attribute)
|
||||||
|
regex = re.compile(regex)
|
||||||
|
values = regex.findall(text)
|
||||||
|
return values
|
||||||
|
|
||||||
|
def _get_unique_value(attribute, text):
|
||||||
|
"""Match attribute in text and return unique match.
|
||||||
|
|
||||||
|
:returns: Single match.
|
||||||
|
"""
|
||||||
|
values = _get_values(attribute, text)
|
||||||
|
n = len(values)
|
||||||
|
if n > 1:
|
||||||
|
raise ValueError("found too many values for {}".format(attribute))
|
||||||
|
elif n == 1:
|
||||||
|
return values[0]
|
||||||
|
else:
|
||||||
|
raise ValueError("no value found for {}".format(attribute))
|
||||||
|
|
||||||
|
def _get_line_and_value(attribute, text):
|
||||||
|
"""Match attribute in text. Return the line and the value of the attribute."""
|
||||||
|
regex = '({}\s+=\s+"(.*)";)'.format(attribute)
|
||||||
|
regex = re.compile(regex)
|
||||||
|
value = regex.findall(text)
|
||||||
|
n = len(value)
|
||||||
|
if n > 1:
|
||||||
|
raise ValueError("found too many values for {}".format(attribute))
|
||||||
|
elif n == 1:
|
||||||
|
return value[0]
|
||||||
|
else:
|
||||||
|
raise ValueError("no value found for {}".format(attribute))
|
||||||
|
|
||||||
|
|
||||||
|
def _replace_value(attribute, value, text):
|
||||||
|
"""Search and replace value of attribute in text."""
|
||||||
|
old_line, old_value = _get_line_and_value(attribute, text)
|
||||||
|
new_line = old_line.replace(old_value, value)
|
||||||
|
new_text = text.replace(old_line, new_line)
|
||||||
|
return new_text
|
||||||
|
|
||||||
|
def _fetch_page(url):
|
||||||
|
r = requests.get(url)
|
||||||
|
if r.status_code == requests.codes.ok:
|
||||||
|
return r.json()
|
||||||
|
else:
|
||||||
|
raise ValueError("request for {} failed".format(url))
|
||||||
|
|
||||||
|
def _get_latest_version_pypi(package, extension):
|
||||||
|
"""Get latest version and hash from PyPI."""
|
||||||
|
url = "{}/{}/json".format(INDEX, package)
|
||||||
|
json = _fetch_page(url)
|
||||||
|
|
||||||
|
version = json['info']['version']
|
||||||
|
for release in json['releases'][version]:
|
||||||
|
if release['filename'].endswith(extension):
|
||||||
|
# TODO: In case of wheel we need to do further checks!
|
||||||
|
sha256 = release['digests']['sha256']
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
sha256 = None
|
||||||
|
return version, sha256
|
||||||
|
|
||||||
|
|
||||||
|
def _get_latest_version_github(package, extension):
|
||||||
|
raise ValueError("updating from GitHub is not yet supported.")
|
||||||
|
|
||||||
|
|
||||||
|
FETCHERS = {
|
||||||
|
'fetchFromGitHub' : _get_latest_version_github,
|
||||||
|
'fetchPypi' : _get_latest_version_pypi,
|
||||||
|
'fetchurl' : _get_latest_version_pypi,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_SETUPTOOLS_EXTENSION = 'tar.gz'
|
||||||
|
|
||||||
|
|
||||||
|
FORMATS = {
|
||||||
|
'setuptools' : DEFAULT_SETUPTOOLS_EXTENSION,
|
||||||
|
'wheel' : 'whl'
|
||||||
|
}
|
||||||
|
|
||||||
|
def _determine_fetcher(text):
|
||||||
|
# Count occurences of fetchers.
|
||||||
|
nfetchers = sum(text.count('src = {}'.format(fetcher)) for fetcher in FETCHERS.keys())
|
||||||
|
if nfetchers == 0:
|
||||||
|
raise ValueError("no fetcher.")
|
||||||
|
elif nfetchers > 1:
|
||||||
|
raise ValueError("multiple fetchers.")
|
||||||
|
else:
|
||||||
|
# Then we check which fetcher to use.
|
||||||
|
for fetcher in FETCHERS.keys():
|
||||||
|
if 'src = {}'.format(fetcher) in text:
|
||||||
|
return fetcher
|
||||||
|
|
||||||
|
|
||||||
|
def _determine_extension(text, fetcher):
|
||||||
|
"""Determine what extension is used in the expression.
|
||||||
|
|
||||||
|
If we use:
|
||||||
|
- fetchPypi, we check if format is specified.
|
||||||
|
- fetchurl, we determine the extension from the url.
|
||||||
|
- fetchFromGitHub we simply use `.tar.gz`.
|
||||||
|
"""
|
||||||
|
if fetcher == 'fetchPypi':
|
||||||
|
try:
|
||||||
|
format = _get_unique_value('format', text)
|
||||||
|
except ValueError as e:
|
||||||
|
format = None # format was not given
|
||||||
|
|
||||||
|
try:
|
||||||
|
extension = _get_unique_value('extension', text)
|
||||||
|
except ValueError as e:
|
||||||
|
extension = None # extension was not given
|
||||||
|
|
||||||
|
if extension is None:
|
||||||
|
if format is None:
|
||||||
|
format = 'setuptools'
|
||||||
|
extension = FORMATS[format]
|
||||||
|
|
||||||
|
elif fetcher == 'fetchurl':
|
||||||
|
url = _get_unique_value('url', text)
|
||||||
|
extension = os.path.splitext(url)[1]
|
||||||
|
if 'pypi' not in url:
|
||||||
|
raise ValueError('url does not point to PyPI.')
|
||||||
|
|
||||||
|
elif fetcher == 'fetchFromGitHub':
|
||||||
|
raise ValueError('updating from GitHub is not yet implemented.')
|
||||||
|
|
||||||
|
return extension
|
||||||
|
|
||||||
|
|
||||||
|
def _update_package(path):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Read the expression
|
||||||
|
with open(path, 'r') as f:
|
||||||
|
text = f.read()
|
||||||
|
|
||||||
|
# Determine pname.
|
||||||
|
pname = _get_unique_value('pname', text)
|
||||||
|
|
||||||
|
# Determine version.
|
||||||
|
version = _get_unique_value('version', text)
|
||||||
|
|
||||||
|
# First we check how many fetchers are mentioned.
|
||||||
|
fetcher = _determine_fetcher(text)
|
||||||
|
|
||||||
|
extension = _determine_extension(text, fetcher)
|
||||||
|
|
||||||
|
new_version, new_sha256 = _get_latest_version_pypi(pname, extension)
|
||||||
|
|
||||||
|
if new_version == version:
|
||||||
|
logging.info("Path {}: no update available for {}.".format(path, pname))
|
||||||
|
return False
|
||||||
|
if not new_sha256:
|
||||||
|
raise ValueError("no file available for {}.".format(pname))
|
||||||
|
|
||||||
|
text = _replace_value('version', new_version, text)
|
||||||
|
text = _replace_value('sha256', new_sha256, text)
|
||||||
|
|
||||||
|
with open(path, 'w') as f:
|
||||||
|
f.write(text)
|
||||||
|
|
||||||
|
logging.info("Path {}: updated {} from {} to {}".format(path, pname, version, new_version))
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _update(path):
|
||||||
|
|
||||||
|
# We need to read and modify a Nix expression.
|
||||||
|
if os.path.isdir(path):
|
||||||
|
path = os.path.join(path, 'default.nix')
|
||||||
|
|
||||||
|
# If a default.nix does not exist, we quit.
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
logging.info("Path {}: does not exist.".format(path))
|
||||||
|
return False
|
||||||
|
|
||||||
|
# If file is not a Nix expression, we quit.
|
||||||
|
if not path.endswith(".nix"):
|
||||||
|
logging.info("Path {}: does not end with `.nix`.".format(path))
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
return _update_package(path)
|
||||||
|
except ValueError as e:
|
||||||
|
logging.warning("Path {}: {}".format(path, e))
|
||||||
|
return False
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('package', type=str, nargs='+')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
packages = map(os.path.abspath, args.package)
|
||||||
|
|
||||||
|
count = list(map(_update, packages))
|
||||||
|
|
||||||
|
logging.info("{} package(s) updated".format(sum(count)))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -16,7 +16,7 @@ containers.database =
|
|||||||
{ config =
|
{ config =
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
{ services.postgresql.enable = true;
|
{ services.postgresql.enable = true;
|
||||||
services.postgresql.package = pkgs.postgresql92;
|
services.postgresql.package = pkgs.postgresql96;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|||||||
@@ -29,8 +29,10 @@ line. For instance, to create a container that has
|
|||||||
<literal>root</literal>:
|
<literal>root</literal>:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
# nixos-container create foo --config 'services.openssh.enable = true; \
|
# nixos-container create foo --config '
|
||||||
users.extraUsers.root.openssh.authorizedKeys.keys = ["ssh-dss AAAAB3N…"];'
|
services.openssh.enable = true;
|
||||||
|
users.extraUsers.root.openssh.authorizedKeys.keys = ["ssh-dss AAAAB3N…"];
|
||||||
|
'
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
@@ -55,7 +57,7 @@ Thus, if something went wrong, you can get status info using
|
|||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>If the container has started succesfully, you can log in as
|
<para>If the container has started successfully, you can log in as
|
||||||
root using the <command>root-login</command> operation:
|
root using the <command>root-login</command> operation:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
@@ -97,8 +99,11 @@ This will build and activate the new configuration. You can also
|
|||||||
specify a new configuration on the command line:
|
specify a new configuration on the command line:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
# nixos-container update foo --config 'services.httpd.enable = true; \
|
# nixos-container update foo --config '
|
||||||
services.httpd.adminAddr = "foo@example.org";'
|
services.httpd.enable = true;
|
||||||
|
services.httpd.adminAddr = "foo@example.org";
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||||
|
'
|
||||||
|
|
||||||
# curl http://$(nixos-container show-ip foo)/
|
# curl http://$(nixos-container show-ip foo)/
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">…
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">…
|
||||||
|
|||||||
@@ -35,6 +35,12 @@ or <literal>ext4</literal>, then it’s best to specify
|
|||||||
<option>fsType</option> to ensure that the kernel module is
|
<option>fsType</option> to ensure that the kernel module is
|
||||||
available.</para>
|
available.</para>
|
||||||
|
|
||||||
|
<note><para>System startup will fail if any of the filesystems fails to mount,
|
||||||
|
dropping you to the emergency shell.
|
||||||
|
You can make a mount asynchronous and non-critical by adding
|
||||||
|
<literal>options = [ "nofail" ];</literal>.
|
||||||
|
</para></note>
|
||||||
|
|
||||||
<xi:include href="luks-file-systems.xml" />
|
<xi:include href="luks-file-systems.xml" />
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|||||||
@@ -113,7 +113,8 @@ manual</link> for the rest.</para>
|
|||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>assert 1 + 1 == 2; "yes!"</literal></entry>
|
<entry><literal>assert 1 + 1 == 2; "yes!"</literal></entry>
|
||||||
<entry>Assertion check (evaluates to <literal>"yes!"</literal>)</entry>
|
<entry>Assertion check (evaluates to <literal>"yes!"</literal>). See <xref
|
||||||
|
linkend="sec-assertions"/> for using assertions in modules</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>let x = "foo"; y = "bar"; in x + y</literal></entry>
|
<entry><literal>let x = "foo"; y = "bar"; in x + y</literal></entry>
|
||||||
|
|||||||
@@ -45,6 +45,13 @@ services.xserver.displayManager.lightdm.enable = true;
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>You can set the keyboard layout (and optionally the layout variant):
|
||||||
|
<programlisting>
|
||||||
|
services.xserver.layout = "de";
|
||||||
|
services.xserver.xkbVariant = "neo";
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>The X server is started automatically at boot time. If you
|
<para>The X server is started automatically at boot time. If you
|
||||||
don’t want this to happen, you can set:
|
don’t want this to happen, you can set:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ let
|
|||||||
chmod -R u+w .
|
chmod -R u+w .
|
||||||
ln -s ${modulesDoc} configuration/modules.xml
|
ln -s ${modulesDoc} configuration/modules.xml
|
||||||
ln -s ${optionsDocBook} options-db.xml
|
ln -s ${optionsDocBook} options-db.xml
|
||||||
echo "${version}" > version
|
printf "%s" "${version}" > version
|
||||||
'';
|
'';
|
||||||
|
|
||||||
toc = builtins.toFile "toc.xml"
|
toc = builtins.toFile "toc.xml"
|
||||||
@@ -94,25 +94,43 @@ let
|
|||||||
"--stringparam chunk.toc ${toc}"
|
"--stringparam chunk.toc ${toc}"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
manual-combined = runCommand "nixos-manual-combined"
|
||||||
|
{ inherit sources;
|
||||||
|
buildInputs = [ libxml2 libxslt ];
|
||||||
|
meta.description = "The NixOS manual as plain docbook XML";
|
||||||
|
}
|
||||||
|
''
|
||||||
|
${copySources}
|
||||||
|
|
||||||
|
xmllint --xinclude --output ./manual-combined.xml ./manual.xml
|
||||||
|
xmllint --xinclude --noxincludenode \
|
||||||
|
--output ./man-pages-combined.xml ./man-pages.xml
|
||||||
|
|
||||||
|
xmllint --debug --noout --nonet \
|
||||||
|
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
||||||
|
manual-combined.xml
|
||||||
|
xmllint --debug --noout --nonet \
|
||||||
|
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
||||||
|
man-pages-combined.xml
|
||||||
|
|
||||||
|
|
||||||
|
mkdir $out
|
||||||
|
cp manual-combined.xml $out/
|
||||||
|
cp man-pages-combined.xml $out/
|
||||||
|
'';
|
||||||
|
|
||||||
olinkDB = runCommand "manual-olinkdb"
|
olinkDB = runCommand "manual-olinkdb"
|
||||||
{ inherit sources;
|
{ inherit sources;
|
||||||
buildInputs = [ libxml2 libxslt ];
|
buildInputs = [ libxml2 libxslt ];
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
${copySources}
|
|
||||||
|
|
||||||
xsltproc \
|
xsltproc \
|
||||||
${manualXsltprocOptions} \
|
${manualXsltprocOptions} \
|
||||||
--stringparam collect.xref.targets only \
|
--stringparam collect.xref.targets only \
|
||||||
--stringparam targets.filename "$out/manual.db" \
|
--stringparam targets.filename "$out/manual.db" \
|
||||||
--nonet --xinclude \
|
--nonet \
|
||||||
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
||||||
./manual.xml
|
${manual-combined}/manual-combined.xml
|
||||||
|
|
||||||
# Check the validity of the man pages sources.
|
|
||||||
xmllint --noout --nonet --xinclude --noxincludenode \
|
|
||||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
|
||||||
./man-pages.xml
|
|
||||||
|
|
||||||
cat > "$out/olinkdb.xml" <<EOF
|
cat > "$out/olinkdb.xml" <<EOF
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
@@ -158,21 +176,15 @@ in rec {
|
|||||||
allowedReferences = ["out"];
|
allowedReferences = ["out"];
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
${copySources}
|
|
||||||
|
|
||||||
# Check the validity of the manual sources.
|
|
||||||
xmllint --noout --nonet --xinclude --noxincludenode \
|
|
||||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
|
||||||
manual.xml
|
|
||||||
|
|
||||||
# Generate the HTML manual.
|
# Generate the HTML manual.
|
||||||
dst=$out/share/doc/nixos
|
dst=$out/share/doc/nixos
|
||||||
mkdir -p $dst
|
mkdir -p $dst
|
||||||
xsltproc \
|
xsltproc \
|
||||||
${manualXsltprocOptions} \
|
${manualXsltprocOptions} \
|
||||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||||
--nonet --xinclude --output $dst/ \
|
--nonet --output $dst/ \
|
||||||
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl ./manual.xml
|
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
||||||
|
${manual-combined}/manual-combined.xml
|
||||||
|
|
||||||
mkdir -p $dst/images/callouts
|
mkdir -p $dst/images/callouts
|
||||||
cp ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
|
cp ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
|
||||||
@@ -190,13 +202,6 @@ in rec {
|
|||||||
buildInputs = [ libxml2 libxslt zip ];
|
buildInputs = [ libxml2 libxslt zip ];
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
${copySources}
|
|
||||||
|
|
||||||
# Check the validity of the manual sources.
|
|
||||||
xmllint --noout --nonet --xinclude --noxincludenode \
|
|
||||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
|
||||||
manual.xml
|
|
||||||
|
|
||||||
# Generate the epub manual.
|
# Generate the epub manual.
|
||||||
dst=$out/share/doc/nixos
|
dst=$out/share/doc/nixos
|
||||||
|
|
||||||
@@ -204,10 +209,11 @@ in rec {
|
|||||||
${manualXsltprocOptions} \
|
${manualXsltprocOptions} \
|
||||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||||
--nonet --xinclude --output $dst/epub/ \
|
--nonet --xinclude --output $dst/epub/ \
|
||||||
${docbook5_xsl}/xml/xsl/docbook/epub/docbook.xsl ./manual.xml
|
${docbook5_xsl}/xml/xsl/docbook/epub/docbook.xsl \
|
||||||
|
${manual-combined}/manual-combined.xml
|
||||||
|
|
||||||
mkdir -p $dst/epub/OEBPS/images/callouts
|
mkdir -p $dst/epub/OEBPS/images/callouts
|
||||||
cp -r ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/epub/OEBPS/images/callouts
|
cp -r ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/epub/OEBPS/images/callouts # */
|
||||||
echo "application/epub+zip" > mimetype
|
echo "application/epub+zip" > mimetype
|
||||||
manual="$dst/nixos-manual.epub"
|
manual="$dst/nixos-manual.epub"
|
||||||
zip -0Xq "$manual" mimetype
|
zip -0Xq "$manual" mimetype
|
||||||
@@ -227,23 +233,16 @@ in rec {
|
|||||||
allowedReferences = ["out"];
|
allowedReferences = ["out"];
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
${copySources}
|
|
||||||
|
|
||||||
# Check the validity of the man pages sources.
|
|
||||||
xmllint --noout --nonet --xinclude --noxincludenode \
|
|
||||||
--relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
|
|
||||||
./man-pages.xml
|
|
||||||
|
|
||||||
# Generate manpages.
|
# Generate manpages.
|
||||||
mkdir -p $out/share/man
|
mkdir -p $out/share/man
|
||||||
xsltproc --nonet --xinclude \
|
xsltproc --nonet \
|
||||||
--param man.output.in.separate.dir 1 \
|
--param man.output.in.separate.dir 1 \
|
||||||
--param man.output.base.dir "'$out/share/man/'" \
|
--param man.output.base.dir "'$out/share/man/'" \
|
||||||
--param man.endnotes.are.numbered 0 \
|
--param man.endnotes.are.numbered 0 \
|
||||||
--param man.break.after.slash 1 \
|
--param man.break.after.slash 1 \
|
||||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
||||||
${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
|
${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
|
||||||
./man-pages.xml
|
${manual-combined}/man-pages-combined.xml
|
||||||
'';
|
'';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-assertions">
|
||||||
|
|
||||||
|
<title>Warnings and Assertions</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
When configuration problems are detectable in a module, it is a good
|
||||||
|
idea to write an assertion or warning. Doing so provides clear
|
||||||
|
feedback to the user and prevents errors after the build.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Although Nix has the <literal>abort</literal> and
|
||||||
|
<literal>builtins.trace</literal> <link xlink:href="https://nixos.org/nix/manual/#ssec-builtins">functions</link> to perform such tasks,
|
||||||
|
they are not ideally suited for NixOS modules. Instead of these
|
||||||
|
functions, you can declare your warnings and assertions using the
|
||||||
|
NixOS module system.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
|
||||||
|
<title>Warnings</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
This is an example of using <literal>warnings</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[
|
||||||
|
{ config, lib, ... }:
|
||||||
|
{
|
||||||
|
config = lib.mkIf config.services.foo.enable {
|
||||||
|
warnings =
|
||||||
|
if config.services.foo.bar
|
||||||
|
then [ ''You have enabled the bar feature of the foo service.
|
||||||
|
This is known to cause some specific problems in certain situations.
|
||||||
|
'' ]
|
||||||
|
else [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
|
||||||
|
<title>Assertions</title>
|
||||||
|
|
||||||
|
|
||||||
|
<para>
|
||||||
|
This example, extracted from the
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/release-17.09/nixos/modules/services/logging/syslogd.nix">
|
||||||
|
<literal>syslogd</literal> module
|
||||||
|
</link> shows how to use <literal>assertions</literal>. Since there
|
||||||
|
can only be one active syslog daemon at a time, an assertion is useful to
|
||||||
|
prevent such a broken system from being built.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[
|
||||||
|
{ config, lib, ... }:
|
||||||
|
{
|
||||||
|
config = lib.mkIf config.services.syslogd.enable {
|
||||||
|
assertions =
|
||||||
|
[ { assertion = !config.services.rsyslogd.enable;
|
||||||
|
message = "rsyslogd conflicts with syslogd";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</section>
|
||||||
@@ -12,12 +12,12 @@ your <filename>configuration.nix</filename> to configure the system that
|
|||||||
would be installed on the CD.</para>
|
would be installed on the CD.</para>
|
||||||
|
|
||||||
<para>Default CD/DVD configurations are available
|
<para>Default CD/DVD configurations are available
|
||||||
inside <filename>nixos/modules/installer/cd-dvd</filename>. To build them
|
inside <filename>nixos/modules/installer/cd-dvd</filename>.
|
||||||
you have to set <envar>NIXOS_CONFIG</envar> before
|
|
||||||
running <command>nix-build</command> to build the ISO.
|
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd-dvd/installation-cd-minimal.nix</screen>
|
$ git clone https://github.com/NixOS/nixpkgs.git
|
||||||
|
$ cd nixpkgs/nixos
|
||||||
|
$ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd-dvd/installation-cd-minimal.nix default.nix</screen>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,9 @@ options = {
|
|||||||
<term><varname>default</varname></term>
|
<term><varname>default</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>The default value used if no value is defined by any
|
<para>The default value used if no value is defined by any
|
||||||
module. A default is not required; in that case, if the option
|
module. A default is not required; but if a default is not given,
|
||||||
value is never used, an error will be thrown.</para>
|
then users of the module will have to define the value of the
|
||||||
|
option, otherwise an error will be thrown.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
@@ -95,7 +96,7 @@ options = {
|
|||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>Both approachs have problems.</para>
|
<para>Both approaches have problems.</para>
|
||||||
|
|
||||||
<para>Making backends independent can quickly become hard to manage. For
|
<para>Making backends independent can quickly become hard to manage. For
|
||||||
display managers, there can be only one enabled at a time, but the type
|
display managers, there can be only one enabled at a time, but the type
|
||||||
@@ -136,8 +137,8 @@ services.xserver.displayManager.enable = mkOption {
|
|||||||
};</screen></example>
|
};</screen></example>
|
||||||
|
|
||||||
<example xml:id='ex-option-declaration-eot-backend-sddm'><title>Extending
|
<example xml:id='ex-option-declaration-eot-backend-sddm'><title>Extending
|
||||||
<literal>services.foo.backend</literal> in the <literal>sddm</literal>
|
<literal>services.xserver.displayManager.enable</literal> in the
|
||||||
module</title>
|
<literal>sddm</literal> module</title>
|
||||||
<screen>
|
<screen>
|
||||||
services.xserver.displayManager.enable = mkOption {
|
services.xserver.displayManager.enable = mkOption {
|
||||||
type = with types; nullOr (enum [ "sddm" ]);
|
type = with types; nullOr (enum [ "sddm" ]);
|
||||||
|
|||||||
@@ -68,8 +68,7 @@
|
|||||||
|
|
||||||
<section><title>Value Types</title>
|
<section><title>Value Types</title>
|
||||||
|
|
||||||
<para>Value types are type that take a value parameter. The only value type
|
<para>Value types are type that take a value parameter.</para>
|
||||||
in the library is <literal>enum</literal>.</para>
|
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@@ -141,33 +140,43 @@
|
|||||||
str</literal>. Multiple definitions cannot be
|
str</literal>. Multiple definitions cannot be
|
||||||
merged.</para></listitem>
|
merged.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>types.coercedTo</varname> <replaceable>from</replaceable>
|
||||||
|
<replaceable>f</replaceable> <replaceable>to</replaceable></term>
|
||||||
|
<listitem><para>Type <replaceable>to</replaceable> or type
|
||||||
|
<replaceable>from</replaceable> which will be coerced to
|
||||||
|
type <replaceable>to</replaceable> using function
|
||||||
|
<replaceable>f</replaceable> which takes an argument of type
|
||||||
|
<replaceable>from</replaceable> and return a value of type
|
||||||
|
<replaceable>to</replaceable>. Can be used to preserve backwards
|
||||||
|
compatibility of an option if its type was changed.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id='section-option-types-submodule'><title>Submodule</title>
|
<section xml:id='section-option-types-submodule'><title>Submodule</title>
|
||||||
|
|
||||||
<para>Submodule is a very powerful type that defines a set of sub-options that
|
<para><literal>submodule</literal> is a very powerful type that defines a set
|
||||||
are handled like a separate module.
|
of sub-options that are handled like a separate module.</para>
|
||||||
It is especially interesting when used with composed types like
|
|
||||||
<literal>attrsOf</literal> or <literal>listOf</literal>.</para>
|
|
||||||
|
|
||||||
<para>The submodule type take a parameter <replaceable>o</replaceable>, that
|
<para>It takes a parameter <replaceable>o</replaceable>, that should be a set,
|
||||||
should be a set, or a function returning a set with an
|
or a function returning a set with an <literal>options</literal> key
|
||||||
<literal>options</literal> key defining the sub-options.
|
defining the sub-options.
|
||||||
The option set can be defined directly (<xref linkend='ex-submodule-direct'
|
Submodule option definitions are type-checked accordingly to the
|
||||||
/>) or as reference (<xref linkend='ex-submodule-reference' />).</para>
|
<literal>options</literal> declarations.
|
||||||
|
Of course, you can nest submodule option definitons for even higher
|
||||||
|
modularity.</para>
|
||||||
|
|
||||||
<para>Submodule option definitions are type-checked accordingly to the options
|
<para>The option set can be defined directly
|
||||||
declarations. It is possible to declare submodule options inside a submodule
|
(<xref linkend='ex-submodule-direct' />) or as reference
|
||||||
sub-options for even higher modularity.</para>
|
(<xref linkend='ex-submodule-reference' />).</para>
|
||||||
|
|
||||||
<example xml:id='ex-submodule-direct'><title>Directly defined submodule</title>
|
<example xml:id='ex-submodule-direct'><title>Directly defined submodule</title>
|
||||||
<screen>
|
<screen>
|
||||||
options.mod = mkOption {
|
options.mod = mkOption {
|
||||||
name = "mod";
|
|
||||||
description = "submodule example";
|
description = "submodule example";
|
||||||
type = with types; listOf (submodule {
|
type = with types; submodule {
|
||||||
options = {
|
options = {
|
||||||
foo = mkOption {
|
foo = mkOption {
|
||||||
type = int;
|
type = int;
|
||||||
@@ -176,10 +185,10 @@ options.mod = mkOption {
|
|||||||
type = str;
|
type = str;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
});
|
};
|
||||||
};</screen></example>
|
};</screen></example>
|
||||||
|
|
||||||
<example xml:id='ex-submodule-reference'><title>Submodule defined as a
|
<example xml:id='ex-submodule-reference'><title>Submodule defined as a
|
||||||
reference</title>
|
reference</title>
|
||||||
<screen>
|
<screen>
|
||||||
let
|
let
|
||||||
@@ -196,16 +205,20 @@ let
|
|||||||
in
|
in
|
||||||
options.mod = mkOption {
|
options.mod = mkOption {
|
||||||
description = "submodule example";
|
description = "submodule example";
|
||||||
type = with types; listOf (submodule modOptions);
|
type = with types; submodule modOptions;
|
||||||
};</screen></example>
|
};</screen></example>
|
||||||
|
|
||||||
<section><title>Composed with <literal>listOf</literal></title>
|
<para>The <literal>submodule</literal> type is especially interesting when
|
||||||
|
used with composed types like <literal>attrsOf</literal> or
|
||||||
<para>When composed with <literal>listOf</literal>, submodule allows multiple
|
<literal>listOf</literal>.
|
||||||
definitions of the submodule option set.</para>
|
When composed with <literal>listOf</literal>
|
||||||
|
(<xref linkend='ex-submodule-listof-declaration' />),
|
||||||
|
<literal>submodule</literal> allows multiple definitions of the submodule
|
||||||
|
option set (<xref linkend='ex-submodule-listof-definition' />).</para>
|
||||||
|
|
||||||
|
|
||||||
<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list
|
<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list
|
||||||
of submodules</title>
|
nof submodules</title>
|
||||||
<screen>
|
<screen>
|
||||||
options.mod = mkOption {
|
options.mod = mkOption {
|
||||||
description = "submodule example";
|
description = "submodule example";
|
||||||
@@ -229,13 +242,11 @@ config.mod = [
|
|||||||
{ foo = 2; bar = "two"; }
|
{ foo = 2; bar = "two"; }
|
||||||
];</screen></example>
|
];</screen></example>
|
||||||
|
|
||||||
</section>
|
<para>When composed with <literal>attrsOf</literal>
|
||||||
|
(<xref linkend='ex-submodule-attrsof-declaration' />),
|
||||||
|
<literal>submodule</literal> allows multiple named definitions of the
|
||||||
<section><title>Composed with <literal>attrsOf</literal></title>
|
submodule option set (<xref linkend='ex-submodule-attrsof-definition' />).
|
||||||
|
</para>
|
||||||
<para>When composed with <literal>attrsOf</literal>, submodule allows multiple
|
|
||||||
named definitions of the submodule option set.</para>
|
|
||||||
|
|
||||||
<example xml:id='ex-submodule-attrsof-declaration'><title>Declaration of
|
<example xml:id='ex-submodule-attrsof-declaration'><title>Declaration of
|
||||||
attribute sets of submodules</title>
|
attribute sets of submodules</title>
|
||||||
@@ -260,7 +271,6 @@ options.mod = mkOption {
|
|||||||
config.mod.one = { foo = 1; bar = "one"; };
|
config.mod.one = { foo = 1; bar = "one"; };
|
||||||
config.mod.two = { foo = 2; bar = "two"; };</screen></example>
|
config.mod.two = { foo = 2; bar = "two"; };</screen></example>
|
||||||
|
|
||||||
</section>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section><title>Extending types</title>
|
<section><title>Extending types</title>
|
||||||
@@ -282,7 +292,7 @@ config.mod.two = { foo = 2; bar = "two"; };</screen></example>
|
|||||||
<screen>
|
<screen>
|
||||||
byte = mkOption {
|
byte = mkOption {
|
||||||
description = "An integer between 0 and 255.";
|
description = "An integer between 0 and 255.";
|
||||||
type = addCheck (x: x >= 0 && x <= 255) types.int;
|
type = addCheck types.int (x: x >= 0 && x <= 255);
|
||||||
};</screen></example>
|
};</screen></example>
|
||||||
|
|
||||||
<example xml:id='ex-extending-type-check-2'><title>Overriding a type
|
<example xml:id='ex-extending-type-check-2'><title>Overriding a type
|
||||||
@@ -386,7 +396,7 @@ code before creating a new type.</para>
|
|||||||
<listitem><para>For composed types that can take a submodule as type
|
<listitem><para>For composed types that can take a submodule as type
|
||||||
parameter, this function can be used to substitute the parameter of a
|
parameter, this function can be used to substitute the parameter of a
|
||||||
submodule type. It takes a module as parameter and return the type with
|
submodule type. It takes a module as parameter and return the type with
|
||||||
the submodule options substituted. It is usally defined as a type
|
the submodule options substituted. It is usually defined as a type
|
||||||
function call with a recursive call to
|
function call with a recursive call to
|
||||||
<literal>substSubModules</literal>, e.g for a type
|
<literal>substSubModules</literal>, e.g for a type
|
||||||
<literal>composedType</literal> that take an <literal>elemtype</literal>
|
<literal>composedType</literal> that take an <literal>elemtype</literal>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<title>Release process</title>
|
<title>Release process</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Going through an example of releasing NixOS 15.09:
|
Going through an example of releasing NixOS 17.09:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<section xml:id="one-month-before-the-beta">
|
<section xml:id="one-month-before-the-beta">
|
||||||
@@ -18,13 +18,13 @@
|
|||||||
<itemizedlist spacing="compact">
|
<itemizedlist spacing="compact">
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Send an email to nix-dev mailinglist as a warning about upcoming beta "feature freeze" in a month.
|
Send an email to the nix-devel mailinglist as a warning about upcoming beta "feature freeze" in a month.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Discuss with Eelco Dolstra and the community (via IRC, ML) about what will reach the deadline.
|
Discuss with Eelco Dolstra and the community (via IRC, ML) about what will reach the deadline.
|
||||||
Any issue or Pull Request targeting the release should have assigned milestone.
|
Any issue or Pull Request targeting the release should be included in the release milestone.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
@@ -32,64 +32,6 @@
|
|||||||
<section xml:id="at-beta-release-time">
|
<section xml:id="at-beta-release-time">
|
||||||
<title>At beta release time</title>
|
<title>At beta release time</title>
|
||||||
<itemizedlist spacing="compact">
|
<itemizedlist spacing="compact">
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Rename <literal>rl-unstable.xml</literal> ->
|
|
||||||
<literal>rl-1509.xml</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>git tag -a -m "Release 15.09-beta" 15.09-beta && git push --tags</literal>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
From the master branch run <literal>git checkout -B release-15.09</literal>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<link xlink:href="https://github.com/NixOS/nixos-org-configurations/pull/18">
|
|
||||||
Make sure channel is created at http://nixos.org/channels/.
|
|
||||||
</link>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/settings/branches">
|
|
||||||
Lock the branch on github (so developers can’t force push)
|
|
||||||
</link>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/compare/bdf161ed8d21...6b63c4616790">bump
|
|
||||||
<literal>system.defaultChannel</literal> attribute in
|
|
||||||
<literal>nixos/modules/misc/version.nix</literal></link>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/d6b08acd1ccac0d9d502c4b635e00b04d3387f06">update
|
|
||||||
<literal>versionSuffix</literal> in
|
|
||||||
<literal>nixos/release.nix</literal></link>, use
|
|
||||||
<literal>git log --format=%an|wc -l</literal> to get commit
|
|
||||||
count
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<literal>echo -n "16.03" > .version</literal> in
|
|
||||||
master.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/b8a4095003e27659092892a4708bb3698231a842">pick
|
|
||||||
a new name for unstable branch.</link>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/13559">Create
|
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/13559">Create
|
||||||
@@ -99,26 +41,81 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Use https://lwn.net/Vulnerabilities/ and
|
<literal>git tag -a -s -m "Release 17.09-beta" 17.09-beta && git push --tags</literal>
|
||||||
<link xlink:href="https://github.com/NixOS/nixpkgs/search?utf8=%E2%9C%93&q=vulnerabilities&type=Issues">triage vulnerabilities in an issue</link>.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Create two Hydra jobsets: release-15.09 and release-15.09-small with <literal>stableBranch</literal> set to false
|
From the master branch run <literal>git checkout -B release-17.09</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixos-org-configurations/pull/18">
|
||||||
|
Make sure a channel is created at http://nixos.org/channels/.
|
||||||
|
</link>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/settings/branches">
|
||||||
|
Let a GitHub nixpkgs admin lock the branch on github for you.
|
||||||
|
(so developers can’t force push)
|
||||||
|
</link>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/compare/bdf161ed8d21...6b63c4616790">
|
||||||
|
Bump the <literal>system.defaultChannel</literal> attribute in
|
||||||
|
<literal>nixos/modules/misc/version.nix</literal>
|
||||||
|
</link>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/d6b08acd1ccac0d9d502c4b635e00b04d3387f06">
|
||||||
|
Update <literal>versionSuffix</literal> in
|
||||||
|
<literal>nixos/release.nix</literal></link>, use
|
||||||
|
<literal>git log --format=%an|wc -l</literal> to get the commit
|
||||||
|
count
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>echo -n "18.03" > .version</literal> on
|
||||||
|
master.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/commit/b8a4095003e27659092892a4708bb3698231a842">
|
||||||
|
Pick a new name for the unstable branch.
|
||||||
|
</link>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Create a new release notes file for the upcoming release + 1, in this
|
||||||
|
case <literal>rl-1803.xml</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Create two Hydra jobsets: release-17.09 and release-17.09-small with <literal>stableBranch</literal> set to false.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Edit changelog at
|
Edit changelog at
|
||||||
<literal>nixos/doc/manual/release-notes/rl-1509.xml</literal>
|
<literal>nixos/doc/manual/release-notes/rl-1709.xml</literal>
|
||||||
(double check desktop versions are noted)
|
(double check desktop versions are noted)
|
||||||
</para>
|
</para>
|
||||||
<itemizedlist spacing="compact">
|
<itemizedlist spacing="compact">
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Get all new NixOS modules
|
Get all new NixOS modules
|
||||||
<literal>git diff release-14.12..release-15.09 nixos/modules/module-list.nix|grep ^+</literal>
|
<literal>git diff release-17.03..release-17.09 nixos/modules/module-list.nix|grep ^+</literal>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
@@ -130,9 +127,25 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
<section xml:id="during-beta">
|
||||||
|
<title>During Beta</title>
|
||||||
|
<itemizedlist spacing="compact">
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Monitor the master branch for bugfixes and minor updates
|
||||||
|
and cherry-pick them to the release branch.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</section>
|
||||||
<section xml:id="before-the-final-release">
|
<section xml:id="before-the-final-release">
|
||||||
<title>Before the final release</title>
|
<title>Before the final release</title>
|
||||||
<itemizedlist spacing="compact">
|
<itemizedlist spacing="compact">
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Re-check that the release notes are complete.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Release Nix (currently only Eelco Dolstra can do that).
|
Release Nix (currently only Eelco Dolstra can do that).
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ in {
|
|||||||
<xi:include href="option-declarations.xml" />
|
<xi:include href="option-declarations.xml" />
|
||||||
<xi:include href="option-types.xml" />
|
<xi:include href="option-types.xml" />
|
||||||
<xi:include href="option-def.xml" />
|
<xi:include href="option-def.xml" />
|
||||||
|
<xi:include href="assertions.xml" />
|
||||||
<xi:include href="meta-attributes.xml" />
|
<xi:include href="meta-attributes.xml" />
|
||||||
<xi:include href="replace-modules.xml" />
|
<xi:include href="replace-modules.xml" />
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ a USB stick. You can use the <command>dd</command> utility to write the image:
|
|||||||
<command>dd if=<replaceable>path-to-image</replaceable>
|
<command>dd if=<replaceable>path-to-image</replaceable>
|
||||||
of=<replaceable>/dev/sdb</replaceable></command>. Be careful about specifying the
|
of=<replaceable>/dev/sdb</replaceable></command>. Be careful about specifying the
|
||||||
correct drive; you can use the <command>lsblk</command> command to get a list of
|
correct drive; you can use the <command>lsblk</command> command to get a list of
|
||||||
block devices. If you're on OS X you can run <command>diskutil list</command>
|
block devices. If you're on macOS you can run <command>diskutil list</command>
|
||||||
to see the list of devices; the device you'll use for the USB must be ejected
|
to see the list of devices; the device you'll use for the USB must be ejected
|
||||||
before writing the image.</para>
|
before writing the image.</para>
|
||||||
|
|
||||||
@@ -31,9 +31,14 @@ ISO, copy its contents verbatim to your drive, then either:
|
|||||||
<para>Edit <filename>loader/entries/nixos-livecd.conf</filename> on the drive
|
<para>Edit <filename>loader/entries/nixos-livecd.conf</filename> on the drive
|
||||||
and change the <literal>root=</literal> field in the <literal>options</literal>
|
and change the <literal>root=</literal> field in the <literal>options</literal>
|
||||||
line to point to your drive (see the documentation on <literal>root=</literal>
|
line to point to your drive (see the documentation on <literal>root=</literal>
|
||||||
in <link xlink:href="https://www.kernel.org/doc/Documentation/kernel-parameters.txt">
|
in <link xlink:href="https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt">
|
||||||
the kernel documentation</link> for more details).</para>
|
the kernel documentation</link> for more details).</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>If you want to load the contents of the ISO to ram after bootin
|
||||||
|
(So you can remove the stick after bootup) you can append the parameter
|
||||||
|
<literal>copytoram</literal>to the <literal>options</literal> field.</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|||||||
@@ -37,15 +37,7 @@
|
|||||||
</orderedlist>
|
</orderedlist>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
There are a few modifications you should make in configuration.nix. Enable
|
There are a few modifications you should make in configuration.nix.
|
||||||
the virtualbox guest service in the main block:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
virtualisation.virtualbox.guest.enable = true;
|
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Enable booting:
|
Enable booting:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
hardware.</para></listitem>
|
hardware.</para></listitem>
|
||||||
|
|
||||||
<listitem><para>The NixOS manual is available on virtual console 8
|
<listitem><para>The NixOS manual is available on virtual console 8
|
||||||
(press Alt+F8 to access).</para></listitem>
|
(press Alt+F8 to access) or by running <command>nixos-help</command>.
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
<listitem><para>You get logged in as <literal>root</literal>
|
<listitem><para>You get logged in as <literal>root</literal>
|
||||||
(with empty password).</para></listitem>
|
(with empty password).</para></listitem>
|
||||||
@@ -139,6 +140,11 @@
|
|||||||
the GRUB boot loader is to be installed. Without it, NixOS cannot
|
the GRUB boot loader is to be installed. Without it, NixOS cannot
|
||||||
boot.</para>
|
boot.</para>
|
||||||
|
|
||||||
|
<para>If there are other operating systems running on the machine before
|
||||||
|
installing NixOS, the
|
||||||
|
<option>boot.loader.grub.useOSProber</option> option can be set to
|
||||||
|
<literal>true</literal> to automatically add them to the grub menu.</para>
|
||||||
|
|
||||||
<para>Another critical option is <option>fileSystems</option>,
|
<para>Another critical option is <option>fileSystems</option>,
|
||||||
specifying the file systems that need to be mounted by NixOS.
|
specifying the file systems that need to be mounted by NixOS.
|
||||||
However, you typically don’t need to set it yourself, because
|
However, you typically don’t need to set it yourself, because
|
||||||
|
|||||||
@@ -17,11 +17,16 @@
|
|||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<cmdsynopsis>
|
<cmdsynopsis>
|
||||||
<command>nixos-option</command>
|
<command>nixos-option</command>
|
||||||
<arg choice='plain'><replaceable>option.name</replaceable></arg>
|
<arg>
|
||||||
|
<option>-I</option>
|
||||||
|
<replaceable>path</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg><option>--verbose</option></arg>
|
||||||
|
<arg><option>--xml</option></arg>
|
||||||
|
<arg choice="plain"><replaceable>option.name</replaceable></arg>
|
||||||
</cmdsynopsis>
|
</cmdsynopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
|
||||||
<refsection><title>Description</title>
|
<refsection><title>Description</title>
|
||||||
|
|
||||||
<para>This command evaluates the configuration specified in
|
<para>This command evaluates the configuration specified in
|
||||||
@@ -33,6 +38,45 @@ attributes contained in the attribute set.</para>
|
|||||||
|
|
||||||
</refsection>
|
</refsection>
|
||||||
|
|
||||||
|
<refsection><title>Options</title>
|
||||||
|
|
||||||
|
<para>This command accepts the following options:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-I</option> <replaceable>path</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This option is passed to the underlying
|
||||||
|
<command>nix-instantiate</command> invocation.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--verbose</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This option enables verbose mode, which currently is just
|
||||||
|
the Bash <command>set</command> <option>-x</option> debug mode.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--xml</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This option causes the output to be rendered as XML.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</refsection>
|
||||||
|
|
||||||
<refsection><title>Environment</title>
|
<refsection><title>Environment</title>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
<para>If you encounter problems, please report them on the
|
<para>If you encounter problems, please report them on the
|
||||||
<literal
|
<literal
|
||||||
xlink:href="http://lists.science.uu.nl/mailman/listinfo/nix-dev">nix-dev@lists.science.uu.nl</literal>
|
xlink:href="https://groups.google.com/forum/#!forum/nix-devel">nix-devel</literal>
|
||||||
mailing list or on the <link
|
mailing list or on the <link
|
||||||
xlink:href="irc://irc.freenode.net/#nixos">
|
xlink:href="irc://irc.freenode.net/#nixos">
|
||||||
<literal>#nixos</literal> channel on Freenode</link>. Bugs should
|
<literal>#nixos</literal> channel on Freenode</link>. Bugs should
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
<para>This section lists the release notes for each stable version of NixOS
|
<para>This section lists the release notes for each stable version of NixOS
|
||||||
and current unstable revision.</para>
|
and current unstable revision.</para>
|
||||||
|
|
||||||
|
<xi:include href="rl-1803.xml" />
|
||||||
<xi:include href="rl-1709.xml" />
|
<xi:include href="rl-1709.xml" />
|
||||||
<xi:include href="rl-1703.xml" />
|
<xi:include href="rl-1703.xml" />
|
||||||
<xi:include href="rl-1609.xml" />
|
<xi:include href="rl-1609.xml" />
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ has the following highlights:</para>
|
|||||||
since version 0.0 as well as the most recent <link
|
since version 0.0 as well as the most recent <link
|
||||||
xlink:href="http://www.stackage.org/">Stackage Nightly</link>
|
xlink:href="http://www.stackage.org/">Stackage Nightly</link>
|
||||||
snapshot. The announcement <link
|
snapshot. The announcement <link
|
||||||
xlink:href="http://lists.science.uu.nl/pipermail/nix-dev/2015-September/018138.html">"Full
|
xlink:href="https://nixos.org/nix-dev/2015-September/018138.html">"Full
|
||||||
Stackage Support in Nixpkgs"</link> gives additional
|
Stackage Support in Nixpkgs"</link> gives additional
|
||||||
details.</para>
|
details.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@@ -342,7 +342,7 @@ nix-env -f "<nixpkgs>" -iA haskellPackages.pandoc
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Python 2.6 has been marked as broken (as it no longer recieves
|
Python 2.6 has been marked as broken (as it no longer receives
|
||||||
security updates from upstream).
|
security updates from upstream).
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ services.syncthing = {
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<literal>networking.firewall.allowPing</literal> is now enabled by
|
<literal>networking.firewall.allowPing</literal> is now enabled by
|
||||||
default. Users are encourarged to configure an approiate rate limit for
|
default. Users are encouraged to configure an appropriate rate limit for
|
||||||
their machines using the Kernel interface at
|
their machines using the Kernel interface at
|
||||||
<filename>/proc/sys/net/ipv4/icmp_ratelimit</filename> and
|
<filename>/proc/sys/net/ipv4/icmp_ratelimit</filename> and
|
||||||
<filename>/proc/sys/net/ipv6/icmp/ratelimit</filename> or using the
|
<filename>/proc/sys/net/ipv6/icmp/ratelimit</filename> or using the
|
||||||
|
|||||||
@@ -78,13 +78,13 @@ following incompatible changes:</para>
|
|||||||
our package set it loosely based on the latest available LTS release, i.e.
|
our package set it loosely based on the latest available LTS release, i.e.
|
||||||
LTS 7.x at the time of this writing. New releases of NixOS and Nixpkgs will
|
LTS 7.x at the time of this writing. New releases of NixOS and Nixpkgs will
|
||||||
drop those old names entirely. <link
|
drop those old names entirely. <link
|
||||||
xlink:href="http://lists.science.uu.nl/pipermail/nix-dev/2016-June/020585.html">The
|
xlink:href="https://nixos.org/nix-dev/2016-June/020585.html">The
|
||||||
motivation for this change</link> has been discussed at length on the
|
motivation for this change</link> has been discussed at length on the
|
||||||
<literal>nix-dev</literal> mailing list and in <link
|
<literal>nix-dev</literal> mailing list and in <link
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/issues/14897">Github issue
|
xlink:href="https://github.com/NixOS/nixpkgs/issues/14897">Github issue
|
||||||
#14897</link>. Development strategies for Haskell hackers who want to rely
|
#14897</link>. Development strategies for Haskell hackers who want to rely
|
||||||
on Nix and NixOS have been described in <link
|
on Nix and NixOS have been described in <link
|
||||||
xlink:href="http://lists.science.uu.nl/pipermail/nix-dev/2016-June/020642.html">another
|
xlink:href="https://nixos.org/nix-dev/2016-June/020642.html">another
|
||||||
nix-dev article</link>.</para>
|
nix-dev article</link>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ following incompatible changes:</para>
|
|||||||
streamlined. Desktop users should be able to simply set
|
streamlined. Desktop users should be able to simply set
|
||||||
<programlisting>security.grsecurity.enable = true</programlisting> to get
|
<programlisting>security.grsecurity.enable = true</programlisting> to get
|
||||||
a reasonably secure system without having to sacrifice too much
|
a reasonably secure system without having to sacrifice too much
|
||||||
functionality. See <xref linkend="sec-grsecurity" /> for documentation
|
functionality.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
<listitem><para>Special filesystems, like <literal>/proc</literal>,
|
<listitem><para>Special filesystems, like <literal>/proc</literal>,
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ following incompatible changes:</para>
|
|||||||
let
|
let
|
||||||
pkgs = import <nixpkgs> {};
|
pkgs = import <nixpkgs> {};
|
||||||
in
|
in
|
||||||
import pkgs.path { overlays = [(self: super: ...)] }
|
import pkgs.path { overlays = [(self: super: ...)]; }
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|||||||
@@ -6,10 +6,24 @@
|
|||||||
|
|
||||||
<title>Release 17.09 (“Hummingbird”, 2017/09/??)</title>
|
<title>Release 17.09 (“Hummingbird”, 2017/09/??)</title>
|
||||||
|
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-17.09-highlights">
|
||||||
|
|
||||||
|
<title>Highlights</title>
|
||||||
|
|
||||||
<para>In addition to numerous new and upgraded packages, this release
|
<para>In addition to numerous new and upgraded packages, this release
|
||||||
has the following highlights: </para>
|
has the following highlights: </para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The GNOME version is now 3.24. KDE Plasma was upgraded to 5.10,
|
||||||
|
KDE Applications to 17.08.1 and KDE Frameworks to 5.37.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The user handling now keeps track of deallocated UIDs/GIDs. When a user
|
The user handling now keeps track of deallocated UIDs/GIDs. When a user
|
||||||
@@ -17,32 +31,465 @@ has the following highlights: </para>
|
|||||||
A consequence is that UIDs and GIDs are no longer reused.
|
A consequence is that UIDs and GIDs are no longer reused.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The module option <option>services.xserver.xrandrHeads</option> now
|
||||||
|
causes the first head specified in this list to be set as the primary
|
||||||
|
head. Apart from that, it's now possible to also set additional options
|
||||||
|
by using an attribute set, for example:
|
||||||
|
<programlisting>
|
||||||
|
{ services.xserver.xrandrHeads = [
|
||||||
|
"HDMI-0"
|
||||||
|
{
|
||||||
|
output = "DVI-0";
|
||||||
|
primary = true;
|
||||||
|
monitorConfig = ''
|
||||||
|
Option "Rotate" "right"
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
This will set the <literal>DVI-0</literal> output to be the primary head,
|
||||||
|
even though <literal>HDMI-0</literal> is the first head in the list.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The handling of SSL in the <literal>services.nginx</literal> module has
|
||||||
|
been cleaned up, renaming the misnamed <literal>enableSSL</literal> to
|
||||||
|
<literal>onlySSL</literal> which reflects its original intention. This
|
||||||
|
is not to be used with the already existing <literal>forceSSL</literal>
|
||||||
|
which creates a second non-SSL virtual host redirecting to the SSL
|
||||||
|
virtual host. This by chance had worked earlier due to specific
|
||||||
|
implementation details. In case you had specified both please remove
|
||||||
|
the <literal>enableSSL</literal> option to keep the previous behaviour.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Another <literal>addSSL</literal> option has been introduced to configure
|
||||||
|
both a non-SSL virtual host and an SSL virtual host with the same
|
||||||
|
configuration.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Options to configure <literal>resolver</literal> options and
|
||||||
|
<literal>upstream</literal> blocks have been introduced. See their information
|
||||||
|
for further details.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The <literal>port</literal> option has been replaced by a more generic
|
||||||
|
<literal>listen</literal> option which makes it possible to specify
|
||||||
|
multiple addresses, ports and SSL configs dependant on the new SSL
|
||||||
|
handling mentioned above.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-17.09-new-services">
|
||||||
|
|
||||||
|
<title>New Services</title>
|
||||||
|
|
||||||
<para>The following new services were added since the last release:</para>
|
<para>The following new services were added since the last release:</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem><para><literal>config/fonts/fontconfig-penultimate.nix</literal></para></listitem>
|
||||||
<para></para>
|
<listitem><para><literal>config/fonts/fontconfig-ultimate.nix</literal></para></listitem>
|
||||||
</listitem>
|
<listitem><para><literal>config/terminfo.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>hardware/sensor/iio.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>hardware/nitrokey.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>hardware/raid/hpsa.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>programs/browserpass.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>programs/gnupg.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>programs/qt5ct.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>programs/slock.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>programs/thefuck.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>security/auditd.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>security/lock-kernel-modules.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>service-managers/docker.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>service-managers/trivial.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/admin/salt/master.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/admin/salt/minion.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/audio/slimserver.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/cluster/kubernetes/default.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/cluster/kubernetes/dns.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/cluster/kubernetes/dashboard.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/continuous-integration/hail.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/databases/clickhouse.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/databases/postage.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/desktops/gnome3/gnome-disks.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/desktops/gnome3/gpaste.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/logging/SystemdJournal2Gelf.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/logging/heartbeat.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/logging/journalwatch.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/logging/syslogd.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/mail/mailhog.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/mail/nullmailer.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/misc/airsonic.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/misc/autorandr.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/misc/exhibitor.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/misc/fstrim.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/misc/gollum.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/misc/irkerd.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/misc/jackett.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/misc/radarr.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/misc/snapper.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/monitoring/osquery.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/monitoring/prometheus/collectd-exporter.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/monitoring/prometheus/fritzbox-exporter.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/network-filesystems/kbfs.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/networking/dnscache.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/networking/fireqos.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/networking/iwd.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/networking/keepalived/default.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/networking/keybase.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/networking/lldpd.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/networking/matterbridge.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/networking/squid.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/networking/tinydns.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/networking/xrdp.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/security/shibboleth-sp.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/security/sks.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/security/sshguard.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/security/torify.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/security/usbguard.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/security/vault.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/system/earlyoom.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/system/saslauthd.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/web-apps/nexus.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/web-apps/pgpkeyserver-lite.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/web-apps/piwik.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/web-servers/lighttpd/collectd.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/web-servers/minio.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/x11/display-managers/xpra.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>services/x11/xautolock.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>tasks/filesystems/bcachefs.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>tasks/powertop.nix</literal></para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-17.09-incompatibilities">
|
||||||
|
|
||||||
|
<title>Backward Incompatibilities</title>
|
||||||
|
|
||||||
<para>When upgrading from a previous release, please be aware of the
|
<para>When upgrading from a previous release, please be aware of the
|
||||||
following incompatible changes:</para>
|
following incompatible changes:</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<emphasis role="strong">
|
||||||
|
In an Qemu-based virtualization environment, the network interface
|
||||||
|
names changed from i.e. <literal>enp0s3</literal> to
|
||||||
|
<literal>ens3</literal>.
|
||||||
|
</emphasis>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This is due to a kernel configuration change. The new naming
|
||||||
|
is consistent with those of other Linux distributions with
|
||||||
|
systemd. See
|
||||||
|
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/29197">#29197</link>
|
||||||
|
for more information.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A machine is affected if the <literal>virt-what</literal> tool
|
||||||
|
either returns <literal>qemu</literal> or
|
||||||
|
<literal>kvm</literal> <emphasis>and</emphasis> has
|
||||||
|
interface names used in any part of its NixOS configuration,
|
||||||
|
in particular if a static network configuration with
|
||||||
|
<literal>networking.interfaces</literal> is used.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Before rebooting affected machines, please ensure:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Change the interface names in your NixOS configuration.
|
||||||
|
The first interface will be called <literal>ens3</literal>,
|
||||||
|
the second one <literal>ens8</literal> and starting from there
|
||||||
|
incremented by 1.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
After changing the interface names, rebuild your system with
|
||||||
|
<literal>nixos-rebuild boot</literal> to activate the new
|
||||||
|
configuration after a reboot. If you switch to the new
|
||||||
|
configuration right away you might lose network connectivity!
|
||||||
|
If using <literal>nixops</literal>, deploy with
|
||||||
|
<literal>nixops deploy --force-reboot</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The following changes apply if the <literal>stateVersion</literal> is changed to 17.09 or higher.
|
||||||
|
For <literal>stateVersion = "17.03"</literal> or lower the old behavior is preserved.
|
||||||
|
</para>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>postgres</literal> default version was changed from 9.5 to 9.6.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>postgres</literal> superuser name has changed from <literal>root</literal> to <literal>postgres</literal> to more closely follow what other Linux distributions are doing.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>postgres</literal> default <literal>dataDir</literal> has changed from <literal>/var/db/postgres</literal> to <literal>/var/lib/postgresql/$psqlSchema</literal> where $psqlSchema is 9.6 for example.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>mysql</literal> default <literal>dataDir</literal> has changed from <literal>/var/mysql</literal> to <literal>/var/lib/mysql</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Radicale's default package has changed from 1.x to 2.x. Instructions to migrate can be found <link xlink:href="http://radicale.org/1to2/"> here </link>. It is also possible to use the newer version by setting the <literal>package</literal> to <literal>radicale2</literal>, which is done automatically when <literal>stateVersion</literal> is 17.09 or higher. The <literal>extraArgs</literal> option has been added to allow passing the data migration arguments specified in the instructions; see the <filename xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/radicale.nix">radicale.nix</filename> NixOS test for an example migration.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>aiccu</literal> package was removed. This is due to SixXS
|
||||||
|
<link xlink:href="https://www.sixxs.net/main/"> sunsetting</link> its IPv6 tunnel.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>fanctl</literal> package and <literal>fan</literal> module
|
||||||
|
have been removed due to the developers not upstreaming their iproute2
|
||||||
|
patches and lagging with compatibility to recent iproute2 versions.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Top-level <literal>idea</literal> package collection was renamed.
|
Top-level <literal>idea</literal> package collection was renamed.
|
||||||
All JetBrains IDEs are now at <literal>jetbrains</literal>.
|
All JetBrains IDEs are now at <literal>jetbrains</literal>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>flexget</literal>'s state database cannot be upgraded to its
|
||||||
|
new internal format, requiring removal of any existing
|
||||||
|
<literal>db-config.sqlite</literal> which will be automatically recreated.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>ipfs</literal> service now doesn't ignore the <literal>dataDir</literal> option anymore. If you've ever set this option to anything other than the default you'll have to either unset it (so the default gets used) or migrate the old data manually with
|
||||||
|
<programlisting>
|
||||||
|
dataDir=<valueOfDataDir>
|
||||||
|
mv /var/lib/ipfs/.ipfs/* $dataDir
|
||||||
|
rmdir /var/lib/ipfs/.ipfs
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>caddy</literal> service was previously using an extra
|
||||||
|
<literal>.caddy</literal> directory in the data directory specified
|
||||||
|
with the <literal>dataDir</literal> option. The contents of the
|
||||||
|
<literal>.caddy</literal> directory are now expected to be in the
|
||||||
|
<literal>dataDir</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>ssh-agent</literal> user service is not started by default
|
||||||
|
anymore. Use <literal>programs.ssh.startAgent</literal> to enable it if
|
||||||
|
needed. There is also a new <literal>programs.gnupg.agent</literal>
|
||||||
|
module that creates a <literal>gpg-agent</literal> user service. It can
|
||||||
|
also serve as a SSH agent if <literal>enableSSHSupport</literal> is set.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>services.tinc.networks.<name>.listenAddress</literal>
|
||||||
|
option had a misleading name that did not correspond to its behavior. It
|
||||||
|
now correctly defines the ip to listen for incoming connections on. To
|
||||||
|
keep the previous behaviour, use
|
||||||
|
<literal>services.tinc.networks.<name>.bindToAddress</literal>
|
||||||
|
instead. Refer to the description of the options for more details.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>tlsdate</literal> package and module were removed. This is due to the project
|
||||||
|
being dead and not building with openssl 1.1.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>wvdial</literal> package and module were removed. This is due to the project
|
||||||
|
being dead and not building with openssl 1.1.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>cc-wrapper</literal>'s setup-hook now exports a number of
|
||||||
|
environment variables corresponding to binutils binaries,
|
||||||
|
(e.g. <envar>LD</envar>, <envar>STRIP</envar>, <envar>RANLIB</envar>,
|
||||||
|
etc). This is done to prevent packages' build systems guessing, which is
|
||||||
|
harder to predict, especially when cross-compiling. However, some packages
|
||||||
|
have broken due to this—their build systems either not supporting, or
|
||||||
|
claiming to support without adequate testing, taking such environment
|
||||||
|
variables as parameters.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>services.firefox.syncserver</literal> now runs by default as a
|
||||||
|
non-root user. To accomodate this change, the default sqlite database
|
||||||
|
location has also been changed. Migration should work automatically.
|
||||||
|
Refer to the description of the options for more details.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>compiz</literal> window manager and package was
|
||||||
|
removed. The system support had been broken for several years.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Touchpad support should now be enabled through
|
||||||
|
<literal>libinput</literal> as <literal>synaptics</literal> is
|
||||||
|
now deprecated. See the option
|
||||||
|
<literal>services.xserver.libinput.enable</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
grsecurity/PaX support has been dropped, following upstream's
|
||||||
|
decision to cease free support. See
|
||||||
|
<link xlink:href="https://grsecurity.net/passing_the_baton.php">
|
||||||
|
upstream's announcement</link> for more information.
|
||||||
|
No complete replacement for grsecurity/PaX is available presently.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>services.mysql</literal> now has declarative
|
||||||
|
configuration of databases and users with the <literal>ensureDatabases</literal> and
|
||||||
|
<literal>ensureUsers</literal> options.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
These options will never delete existing databases and users,
|
||||||
|
especially not when the value of the options are changed.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The MySQL users will be identified using
|
||||||
|
<link xlink:href="https://mariadb.com/kb/en/library/authentication-plugin-unix-socket/">
|
||||||
|
Unix socket authentication</link>. This authenticates the
|
||||||
|
Unix user with the same name only, and that without the need
|
||||||
|
for a password.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
If you have previously created a MySQL <literal>root</literal>
|
||||||
|
user <emphasis>with a password</emphasis>, you will need to add
|
||||||
|
<literal>root</literal> user for unix socket authentication
|
||||||
|
before using the new options. This can be done by running the
|
||||||
|
following SQL script:
|
||||||
|
|
||||||
|
<programlisting language="sql">
|
||||||
|
CREATE USER 'root'@'%' IDENTIFIED BY '';
|
||||||
|
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
|
||||||
|
-- Optionally, delete the password-authenticated user:
|
||||||
|
-- DROP USER 'root'@'localhost';
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>services.mysqlBackup</literal> now works by default
|
||||||
|
without any user setup, including for users other than
|
||||||
|
<literal>mysql</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
By default, the <literal>mysql</literal> user is no longer the
|
||||||
|
user which performs the backup. Instead a system account
|
||||||
|
<literal>mysqlbackup</literal> is used.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The <literal>mysqlBackup</literal> service is also now using
|
||||||
|
systemd timers instead of <literal>cron</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Therefore, the <literal>services.mysqlBackup.period</literal>
|
||||||
|
option no longer exists, and has been replaced with
|
||||||
|
<literal>services.mysqlBackup.calendar</literal>, which is in
|
||||||
|
the format of <link
|
||||||
|
xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.time.html#Calendar%20Events">systemd.time(7)</link>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
If you expect to be sent an e-mail when the backup fails,
|
||||||
|
consider using a script which monitors the systemd journal for
|
||||||
|
errors. Regretfully, at present there is no built-in
|
||||||
|
functionality for this.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
You can check that backups still work by running
|
||||||
|
<command>systemctl start mysql-backup</command> then
|
||||||
|
<command>systemctl status mysql-backup</command>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Templated systemd services e.g <literal>container@name</literal> are
|
||||||
|
now handled currectly when switching to a new configuration, resulting
|
||||||
|
in them being reloaded.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Steam: the <literal>newStdcpp</literal> parameter
|
||||||
|
was removed and should not be needed anymore.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Redis has been updated to version 4 which mandates a cluster
|
||||||
|
mass-restart, due to changes in the network handling, in order
|
||||||
|
to ensure compatibility with networks NATing traffic.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-17.09-notable-changes">
|
||||||
|
|
||||||
<para>Other notable improvements:</para>
|
<title>Other Notable Changes</title>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
|
||||||
@@ -67,7 +514,98 @@ following incompatible changes:</para>
|
|||||||
module where user Fontconfig settings are available.
|
module where user Fontconfig settings are available.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
ZFS/SPL have been updated to 0.7.0, <literal>zfsUnstable, splUnstable</literal>
|
||||||
|
have therefore been removed.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <option>time.timeZone</option> option now allows the value
|
||||||
|
<literal>null</literal> in addition to timezone strings. This value
|
||||||
|
allows changing the timezone of a system imperatively using
|
||||||
|
<command>timedatectl set-timezone</command>. The default timezone
|
||||||
|
is still UTC.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Nixpkgs overlays may now be specified with a file as well as a directory. The
|
||||||
|
value of <literal><nixpkgs-overlays></literal> may be a file, and
|
||||||
|
<filename>~/.config/nixpkgs/overlays.nix</filename> can be used instead of the
|
||||||
|
<filename>~/.config/nixpkgs/overlays</filename> directory.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
See the overlays chapter of the Nixpkgs manual for more details.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Definitions for <filename>/etc/hosts</filename> can now be specified
|
||||||
|
declaratively with <literal>networking.hosts</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Two new options have been added to the installer loader, in addition
|
||||||
|
to the default having changed. The kernel log verbosity has been lowered
|
||||||
|
to the upstream default for the default options, in order to not spam
|
||||||
|
the console when e.g. joining a network.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This therefore leads to adding a new <literal>debug</literal> option
|
||||||
|
to set the log level to the previous verbose mode, to make debugging
|
||||||
|
easier, but still accessible easily.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Additionally a <literal>copytoram</literal> option has been added,
|
||||||
|
which makes it possible to remove the install medium after booting.
|
||||||
|
This allows tethering from your phone after booting from it.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>services.gitlab-runner.configOptions</literal> has been added
|
||||||
|
to specify the configuration of gitlab-runners declaratively.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>services.jenkins.plugins</literal> has been added
|
||||||
|
to install plugins easily, this can be generated with jenkinsPlugins2nix.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>services.postfix.config</literal> has been added
|
||||||
|
to specify the main.cf with NixOS options. Additionally other options
|
||||||
|
have been added to the postfix module and has been improved further.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The GitLab package and module have been updated to the latest 10.0
|
||||||
|
release.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>systemd-boot</literal> boot loader now lists the NixOS
|
||||||
|
version, kernel version and build date of all bootable generations.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The dnscrypt-proxy service now defaults to using a random upstream resolver,
|
||||||
|
selected from the list of public non-logging resolvers with DNSSEC support.
|
||||||
|
Existing configurations can be migrated to this mode of operation by
|
||||||
|
omitting the <option>services.dnscrypt-proxy.resolverName</option> option
|
||||||
|
or setting it to <literal>"random"</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
</section>
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-18.03">
|
||||||
|
|
||||||
|
<title>Release 18.03 (“Impala”, 2018/03/??)</title>
|
||||||
|
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-18.03-highlights">
|
||||||
|
|
||||||
|
<title>Highlights</title>
|
||||||
|
|
||||||
|
<para>In addition to numerous new and upgraded packages, this release
|
||||||
|
has the following highlights: </para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-18.03-new-services">
|
||||||
|
|
||||||
|
<title>New Services</title>
|
||||||
|
|
||||||
|
<para>The following new services were added since the last release:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para></para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-18.03-incompatibilities">
|
||||||
|
|
||||||
|
<title>Backward Incompatibilities</title>
|
||||||
|
|
||||||
|
<para>When upgrading from a previous release, please be aware of the
|
||||||
|
following incompatible changes:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Dollar signs in options under <option>services.postfix</option> are
|
||||||
|
passed verbatim to Postfix, which will interpret them as the beginning of
|
||||||
|
a parameter expression. This was already true for string-valued options
|
||||||
|
in the previous release, but not for list-valued options. If you need to
|
||||||
|
pass literal dollar signs through Postfix, double them.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The <literal>postage</literal> package (for web-based PostgreSQL
|
||||||
|
administration) has been renamed to <literal>pgmanage</literal>. The
|
||||||
|
corresponding module has also been renamed. To migrate please rename all
|
||||||
|
<option>services.postage</option> options to
|
||||||
|
<option>services.pgmanage</option>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="sec-release-18.03-notable-changes">
|
||||||
|
|
||||||
|
<title>Other Notable Changes</title>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
ZNC option <option>services.znc.mutable</option> now defaults to <literal>true</literal>.
|
||||||
|
That means that old configuration is not overwritten by default when update to the znc options are made.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
+117
-81
@@ -33,42 +33,118 @@
|
|||||||
|
|
||||||
, name ? "nixos-disk-image"
|
, name ? "nixos-disk-image"
|
||||||
|
|
||||||
# This prevents errors while checking nix-store validity, see
|
|
||||||
# https://github.com/NixOS/nix/issues/1134
|
|
||||||
, fixValidity ? true
|
|
||||||
|
|
||||||
, format ? "raw"
|
, format ? "raw"
|
||||||
}:
|
}:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
pkgs.vmTools.runInLinuxVM (
|
let
|
||||||
|
extensions = {
|
||||||
|
qcow2 = "qcow2";
|
||||||
|
vpc = "vhd";
|
||||||
|
raw = "img";
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgs = lib.cleanSource pkgs.path;
|
||||||
|
|
||||||
|
channelSources = pkgs.runCommand "nixos-${config.system.nixosVersion}" {} ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp -prd ${nixpkgs} $out/nixos
|
||||||
|
chmod -R u+w $out/nixos
|
||||||
|
if [ ! -e $out/nixos/nixpkgs ]; then
|
||||||
|
ln -s . $out/nixos/nixpkgs
|
||||||
|
fi
|
||||||
|
rm -rf $out/nixos/.git
|
||||||
|
echo -n ${config.system.nixosVersionSuffix} > $out/nixos/.version-suffix
|
||||||
|
'';
|
||||||
|
|
||||||
|
metaClosure = pkgs.writeText "meta" ''
|
||||||
|
${config.system.build.toplevel}
|
||||||
|
${config.nix.package.out}
|
||||||
|
${channelSources}
|
||||||
|
'';
|
||||||
|
|
||||||
|
prepareImageInputs = with pkgs; [ rsync utillinux parted e2fsprogs lkl fakeroot config.system.build.nixos-prepare-root ] ++ stdenv.initialPath;
|
||||||
|
|
||||||
|
# I'm preserving the line below because I'm going to search for it across nixpkgs to consolidate
|
||||||
|
# image building logic. The comment right below this now appears in 4 different places in nixpkgs :)
|
||||||
|
# !!! should use XML.
|
||||||
|
sources = map (x: x.source) contents;
|
||||||
|
targets = map (x: x.target) contents;
|
||||||
|
|
||||||
|
prepareImage = ''
|
||||||
|
export PATH=${pkgs.lib.makeSearchPathOutput "bin" "bin" prepareImageInputs}
|
||||||
|
|
||||||
|
mkdir $out
|
||||||
|
diskImage=nixos.raw
|
||||||
|
truncate -s ${toString diskSize}M $diskImage
|
||||||
|
|
||||||
|
${if partitioned then ''
|
||||||
|
parted --script $diskImage -- mklabel msdos mkpart primary ext4 1M -1s
|
||||||
|
offset=$((2048*512))
|
||||||
|
'' else ''
|
||||||
|
offset=0
|
||||||
|
''}
|
||||||
|
|
||||||
|
mkfs.${fsType} -F -L nixos -E offset=$offset $diskImage
|
||||||
|
|
||||||
|
root="$PWD/root"
|
||||||
|
mkdir -p $root
|
||||||
|
|
||||||
|
# Copy arbitrary other files into the image
|
||||||
|
# Semi-shamelessly copied from make-etc.sh. I (@copumpkin) shall factor this stuff out as part of
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/23052.
|
||||||
|
set -f
|
||||||
|
sources_=(${concatStringsSep " " sources})
|
||||||
|
targets_=(${concatStringsSep " " targets})
|
||||||
|
set +f
|
||||||
|
|
||||||
|
for ((i = 0; i < ''${#targets_[@]}; i++)); do
|
||||||
|
source="''${sources_[$i]}"
|
||||||
|
target="''${targets_[$i]}"
|
||||||
|
|
||||||
|
if [[ "$source" =~ '*' ]]; then
|
||||||
|
# If the source name contains '*', perform globbing.
|
||||||
|
mkdir -p $root/$target
|
||||||
|
for fn in $source; do
|
||||||
|
rsync -a --no-o --no-g "$fn" $root/$target/
|
||||||
|
done
|
||||||
|
else
|
||||||
|
mkdir -p $root/$(dirname $target)
|
||||||
|
if ! [ -e $root/$target ]; then
|
||||||
|
rsync -a --no-o --no-g $source $root/$target
|
||||||
|
else
|
||||||
|
echo "duplicate entry $target -> $source"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# TODO: Nix really likes to chown things it creates to its current user...
|
||||||
|
fakeroot nixos-prepare-root $root ${channelSources} ${config.system.build.toplevel} closure
|
||||||
|
|
||||||
|
echo "copying staging root to image..."
|
||||||
|
cptofs ${pkgs.lib.optionalString partitioned "-P 1"} -t ${fsType} -i $diskImage $root/* /
|
||||||
|
'';
|
||||||
|
in pkgs.vmTools.runInLinuxVM (
|
||||||
pkgs.runCommand name
|
pkgs.runCommand name
|
||||||
{ preVM =
|
{ preVM = prepareImage;
|
||||||
''
|
buildInputs = with pkgs; [ utillinux e2fsprogs ];
|
||||||
mkdir $out
|
exportReferencesGraph = [ "closure" metaClosure ];
|
||||||
diskImage=$out/nixos.${if format == "qcow2" then "qcow2" else "img"}
|
postVM = ''
|
||||||
${pkgs.vmTools.qemu}/bin/qemu-img create -f ${format} $diskImage "${toString diskSize}M"
|
${if format == "raw" then ''
|
||||||
mv closure xchg/
|
mv $diskImage $out/nixos.img
|
||||||
'';
|
diskImage=$out/nixos.img
|
||||||
buildInputs = with pkgs; [ utillinux perl e2fsprogs parted rsync ];
|
'' else ''
|
||||||
|
${pkgs.qemu}/bin/qemu-img convert -f raw -O ${format} $diskImage $out/nixos.${extensions.${format}}
|
||||||
# I'm preserving the line below because I'm going to search for it across nixpkgs to consolidate
|
diskImage=$out/nixos.${extensions.${format}}
|
||||||
# image building logic. The comment right below this now appears in 4 different places in nixpkgs :)
|
''}
|
||||||
# !!! should use XML.
|
${postVM}
|
||||||
sources = map (x: x.source) contents;
|
'';
|
||||||
targets = map (x: x.target) contents;
|
|
||||||
|
|
||||||
exportReferencesGraph =
|
|
||||||
[ "closure" config.system.build.toplevel ];
|
|
||||||
inherit postVM;
|
|
||||||
memSize = 1024;
|
memSize = 1024;
|
||||||
}
|
}
|
||||||
''
|
''
|
||||||
${if partitioned then ''
|
${if partitioned then ''
|
||||||
# Create a single / partition.
|
|
||||||
parted /dev/vda mklabel msdos
|
|
||||||
parted /dev/vda -- mkpart primary ext2 1M -1s
|
|
||||||
. /sys/class/block/vda1/uevent
|
. /sys/class/block/vda1/uevent
|
||||||
mknod /dev/vda1 b $MAJOR $MINOR
|
mknod /dev/vda1 b $MAJOR $MINOR
|
||||||
rootDisk=/dev/vda1
|
rootDisk=/dev/vda1
|
||||||
@@ -76,74 +152,34 @@ pkgs.vmTools.runInLinuxVM (
|
|||||||
rootDisk=/dev/vda
|
rootDisk=/dev/vda
|
||||||
''}
|
''}
|
||||||
|
|
||||||
# Create an empty filesystem and mount it.
|
# Some tools assume these exist
|
||||||
mkfs.${fsType} -L nixos $rootDisk
|
|
||||||
mkdir /mnt
|
|
||||||
mount $rootDisk /mnt
|
|
||||||
|
|
||||||
# Register the paths in the Nix database.
|
|
||||||
printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
|
|
||||||
${config.nix.package.out}/bin/nix-store --load-db --option build-users-group ""
|
|
||||||
|
|
||||||
${if fixValidity then ''
|
|
||||||
# Add missing size/hash fields to the database. FIXME:
|
|
||||||
# exportReferencesGraph should provide these directly.
|
|
||||||
${config.nix.package.out}/bin/nix-store --verify --check-contents --option build-users-group ""
|
|
||||||
'' else ""}
|
|
||||||
|
|
||||||
# In case the bootloader tries to write to /dev/sda…
|
|
||||||
ln -s vda /dev/xvda
|
ln -s vda /dev/xvda
|
||||||
ln -s vda /dev/sda
|
ln -s vda /dev/sda
|
||||||
|
|
||||||
# Install the closure onto the image
|
mountPoint=/mnt
|
||||||
USER=root ${config.system.build.nixos-install}/bin/nixos-install \
|
mkdir $mountPoint
|
||||||
--closure ${config.system.build.toplevel} \
|
mount $rootDisk $mountPoint
|
||||||
--no-channel-copy \
|
|
||||||
--no-root-passwd \
|
|
||||||
${optionalString (!installBootLoader) "--no-bootloader"}
|
|
||||||
|
|
||||||
# Install a configuration.nix.
|
# Install a configuration.nix
|
||||||
mkdir -p /mnt/etc/nixos
|
mkdir -p /mnt/etc/nixos
|
||||||
${optionalString (configFile != null) ''
|
${optionalString (configFile != null) ''
|
||||||
cp ${configFile} /mnt/etc/nixos/configuration.nix
|
cp ${configFile} /mnt/etc/nixos/configuration.nix
|
||||||
''}
|
''}
|
||||||
|
|
||||||
# Remove /etc/machine-id so that each machine cloning this image will get its own id
|
mount --rbind /dev $mountPoint/dev
|
||||||
rm -f /mnt/etc/machine-id
|
mount --rbind /proc $mountPoint/proc
|
||||||
|
mount --rbind /sys $mountPoint/sys
|
||||||
|
|
||||||
# Copy arbitrary other files into the image
|
# Set up core system link, GRUB, etc.
|
||||||
# Semi-shamelessly copied from make-etc.sh. I (@copumpkin) shall factor this stuff out as part of
|
NIXOS_INSTALL_BOOTLOADER=1 chroot $mountPoint /nix/var/nix/profiles/system/bin/switch-to-configuration boot
|
||||||
# https://github.com/NixOS/nixpkgs/issues/23052.
|
|
||||||
set -f
|
|
||||||
sources_=($sources)
|
|
||||||
targets_=($targets)
|
|
||||||
set +f
|
|
||||||
|
|
||||||
for ((i = 0; i < ''${#targets_[@]}; i++)); do
|
# TODO: figure out if I should activate, but for now I won't
|
||||||
source="''${sources_[$i]}"
|
# chroot $mountPoint /nix/var/nix/profiles/system/activate
|
||||||
target="''${targets_[$i]}"
|
|
||||||
|
|
||||||
if [[ "$source" =~ '*' ]]; then
|
# The above scripts will generate a random machine-id and we don't want to bake a single ID into all our images
|
||||||
|
rm -f $mountPoint/etc/machine-id
|
||||||
|
|
||||||
# If the source name contains '*', perform globbing.
|
umount -R /mnt
|
||||||
mkdir -p /mnt/$target
|
|
||||||
for fn in $source; do
|
|
||||||
rsync -a --no-o --no-g "$fn" /mnt/$target/
|
|
||||||
done
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
mkdir -p /mnt/$(dirname $target)
|
|
||||||
if ! [ -e /mnt/$target ]; then
|
|
||||||
rsync -a --no-o --no-g $source /mnt/$target
|
|
||||||
else
|
|
||||||
echo "duplicate entry $target -> $source"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
umount /mnt
|
|
||||||
|
|
||||||
# Make sure resize2fs works. Note that resize2fs has stricter criteria for resizing than a normal
|
# Make sure resize2fs works. Note that resize2fs has stricter criteria for resizing than a normal
|
||||||
# mount, so the `-c 0` and `-i 0` don't affect it. Setting it to `now` doesn't produce deterministic
|
# mount, so the `-c 0` and `-i 0` don't affect it. Setting it to `now` doesn't produce deterministic
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ pkgs.stdenv.mkDerivation {
|
|||||||
echo "Creating an EXT4 image of $bytes bytes (numInodes=$numInodes, numDataBlocks=$numDataBlocks)"
|
echo "Creating an EXT4 image of $bytes bytes (numInodes=$numInodes, numDataBlocks=$numDataBlocks)"
|
||||||
|
|
||||||
truncate -s $bytes $out
|
truncate -s $bytes $out
|
||||||
faketime "1970-01-01 00:00:00" mkfs.ext4 -L ${volumeLabel} -U 44444444-4444-4444-8888-888888888888 $out
|
faketime -f "1970-01-01 00:00:01" mkfs.ext4 -L ${volumeLabel} -U 44444444-4444-4444-8888-888888888888 $out
|
||||||
|
|
||||||
# Populate the image contents by piping a bunch of commands to the `debugfs` tool from e2fsprogs.
|
# Populate the image contents by piping a bunch of commands to the `debugfs` tool from e2fsprogs.
|
||||||
# For example, to copy /nix/store/abcd...efg-coreutils-8.23/bin/sleep:
|
# For example, to copy /nix/store/abcd...efg-coreutils-8.23/bin/sleep:
|
||||||
@@ -76,7 +76,7 @@ pkgs.stdenv.mkDerivation {
|
|||||||
|
|
||||||
echo sif $file gid 30000 # chgrp to nixbld
|
echo sif $file gid 30000 # chgrp to nixbld
|
||||||
done
|
done
|
||||||
) | faketime "1970-01-01 00:00:00" debugfs -w $out -f /dev/stdin > errorlog 2>&1
|
) | faketime -f "1970-01-01 00:00:01" debugfs -w $out -f /dev/stdin > errorlog 2>&1
|
||||||
|
|
||||||
# The debugfs tool doesn't terminate on error nor exit with a non-zero status. Check manually.
|
# The debugfs tool doesn't terminate on error nor exit with a non-zero status. Check manually.
|
||||||
if egrep -q 'Could not allocate|File not found' errorlog; then
|
if egrep -q 'Could not allocate|File not found' errorlog; then
|
||||||
|
|||||||
@@ -219,8 +219,8 @@ sub waitForMonitorPrompt {
|
|||||||
sub retry {
|
sub retry {
|
||||||
my ($coderef) = @_;
|
my ($coderef) = @_;
|
||||||
my $n;
|
my $n;
|
||||||
for ($n = 0; $n < 900; $n++) {
|
for ($n = 899; $n >=0; $n--) {
|
||||||
return if &$coderef;
|
return if &$coderef($n);
|
||||||
sleep 1;
|
sleep 1;
|
||||||
}
|
}
|
||||||
die "action timed out after $n seconds";
|
die "action timed out after $n seconds";
|
||||||
@@ -372,6 +372,17 @@ sub getUnitInfo {
|
|||||||
return $info;
|
return $info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Fail if the given systemd unit is not in the "active" state.
|
||||||
|
sub requireActiveUnit {
|
||||||
|
my ($self, $unit) = @_;
|
||||||
|
$self->nest("checking if unit ‘$unit’ has reached state 'active'", sub {
|
||||||
|
my $info = $self->getUnitInfo($unit);
|
||||||
|
my $state = $info->{ActiveState};
|
||||||
|
if ($state ne "active") {
|
||||||
|
die "Expected unit ‘$unit’ to to be in state 'active' but it is in state ‘$state’\n";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
# Wait for a systemd unit to reach the "active" state.
|
# Wait for a systemd unit to reach the "active" state.
|
||||||
sub waitForUnit {
|
sub waitForUnit {
|
||||||
@@ -518,6 +529,12 @@ sub waitUntilTTYMatches {
|
|||||||
|
|
||||||
$self->nest("waiting for $regexp to appear on tty $tty", sub {
|
$self->nest("waiting for $regexp to appear on tty $tty", sub {
|
||||||
retry sub {
|
retry sub {
|
||||||
|
my ($retries_remaining) = @_;
|
||||||
|
if ($retries_remaining == 0) {
|
||||||
|
$self->log("Last chance to match /$regexp/ on TTY$tty, which currently contains:");
|
||||||
|
$self->log($self->getTTYText($tty));
|
||||||
|
}
|
||||||
|
|
||||||
return 1 if $self->getTTYText($tty) =~ /$regexp/;
|
return 1 if $self->getTTYText($tty) =~ /$regexp/;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -566,6 +583,12 @@ sub waitForText {
|
|||||||
my ($self, $regexp) = @_;
|
my ($self, $regexp) = @_;
|
||||||
$self->nest("waiting for $regexp to appear on the screen", sub {
|
$self->nest("waiting for $regexp to appear on the screen", sub {
|
||||||
retry sub {
|
retry sub {
|
||||||
|
my ($retries_remaining) = @_;
|
||||||
|
if ($retries_remaining == 0) {
|
||||||
|
$self->log("Last chance to match /$regexp/ on the screen, which currently contains:");
|
||||||
|
$self->log($self->getScreenText);
|
||||||
|
}
|
||||||
|
|
||||||
return 1 if $self->getScreenText =~ /$regexp/;
|
return 1 if $self->getScreenText =~ /$regexp/;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -600,6 +623,13 @@ sub waitForWindow {
|
|||||||
$self->nest("waiting for a window to appear", sub {
|
$self->nest("waiting for a window to appear", sub {
|
||||||
retry sub {
|
retry sub {
|
||||||
my @names = $self->getWindowNames;
|
my @names = $self->getWindowNames;
|
||||||
|
|
||||||
|
my ($retries_remaining) = @_;
|
||||||
|
if ($retries_remaining == 0) {
|
||||||
|
$self->log("Last chance to match /$regexp/ on the the window list, which currently contains:");
|
||||||
|
$self->log(join(", ", @names));
|
||||||
|
}
|
||||||
|
|
||||||
foreach my $n (@names) {
|
foreach my $n (@names) {
|
||||||
return 1 if $n =~ /$regexp/;
|
return 1 if $n =~ /$regexp/;
|
||||||
}
|
}
|
||||||
@@ -617,29 +647,19 @@ sub copyFileFromHost {
|
|||||||
|
|
||||||
|
|
||||||
my %charToKey = (
|
my %charToKey = (
|
||||||
'!' => "shift-0x02",
|
'A' => "shift-a", 'N' => "shift-n", '-' => "0x0C", '_' => "shift-0x0C", '!' => "shift-0x02",
|
||||||
'@' => "shift-0x03",
|
'B' => "shift-b", 'O' => "shift-o", '=' => "0x0D", '+' => "shift-0x0D", '@' => "shift-0x03",
|
||||||
'#' => "shift-0x04",
|
'C' => "shift-c", 'P' => "shift-p", '[' => "0x1A", '{' => "shift-0x1A", '#' => "shift-0x04",
|
||||||
'$' => "shift-0x05",
|
'D' => "shift-d", 'Q' => "shift-q", ']' => "0x1B", '}' => "shift-0x1B", '$' => "shift-0x05",
|
||||||
'%' => "shift-0x06",
|
'E' => "shift-e", 'R' => "shift-r", ';' => "0x27", ':' => "shift-0x27", '%' => "shift-0x06",
|
||||||
'^' => "shift-0x07",
|
'F' => "shift-f", 'S' => "shift-s", '\'' => "0x28", '"' => "shift-0x28", '^' => "shift-0x07",
|
||||||
'&' => "shift-0x08",
|
'G' => "shift-g", 'T' => "shift-t", '`' => "0x29", '~' => "shift-0x29", '&' => "shift-0x08",
|
||||||
'*' => "shift-0x09",
|
'H' => "shift-h", 'U' => "shift-u", '\\' => "0x2B", '|' => "shift-0x2B", '*' => "shift-0x09",
|
||||||
'(' => "shift-0x0A",
|
'I' => "shift-i", 'V' => "shift-v", ',' => "0x33", '<' => "shift-0x33", '(' => "shift-0x0A",
|
||||||
')' => "shift-0x0B",
|
'J' => "shift-j", 'W' => "shift-w", '.' => "0x34", '>' => "shift-0x34", ')' => "shift-0x0B",
|
||||||
'-' => "0x0C", '_' => "shift-0x0C",
|
'K' => "shift-k", 'X' => "shift-x", '/' => "0x35", '?' => "shift-0x35",
|
||||||
'=' => "0x0D", '+' => "shift-0x0D",
|
'L' => "shift-l", 'Y' => "shift-y", ' ' => "spc",
|
||||||
'[' => "0x1A", '{' => "shift-0x1A",
|
'M' => "shift-m", 'Z' => "shift-z", "\n" => "ret",
|
||||||
']' => "0x1B", '}' => "shift-0x1B",
|
|
||||||
';' => "0x27", ':' => "shift-0x27",
|
|
||||||
'\'' => "0x28", '"' => "shift-0x28",
|
|
||||||
'`' => "0x29", '~' => "shift-0x29",
|
|
||||||
'\\' => "0x2B", '|' => "shift-0x2B",
|
|
||||||
',' => "0x33", '<' => "shift-0x33",
|
|
||||||
'.' => "0x34", '>' => "shift-0x34",
|
|
||||||
'/' => "0x35", '?' => "shift-0x35",
|
|
||||||
' ' => "spc",
|
|
||||||
"\n" => "ret",
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ foreach my $vlan (split / /, $ENV{VLANS} || "") {
|
|||||||
if ($pid == 0) {
|
if ($pid == 0) {
|
||||||
dup2(fileno($pty->slave), 0);
|
dup2(fileno($pty->slave), 0);
|
||||||
dup2(fileno($stdoutW), 1);
|
dup2(fileno($stdoutW), 1);
|
||||||
exec "vde_switch -s $socket" or _exit(1);
|
exec "vde_switch -s $socket --dirmode 0700" or _exit(1);
|
||||||
}
|
}
|
||||||
close $stdoutW;
|
close $stdoutW;
|
||||||
print $pty "version\n";
|
print $pty "version\n";
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ rec {
|
|||||||
{ key = "run-in-machine";
|
{ key = "run-in-machine";
|
||||||
networking.hostName = "client";
|
networking.hostName = "client";
|
||||||
nix.readOnlyStore = false;
|
nix.readOnlyStore = false;
|
||||||
|
virtualisation.writableStore = false;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ let
|
|||||||
excludedOptions = [
|
excludedOptions = [
|
||||||
"boot.systemd.services"
|
"boot.systemd.services"
|
||||||
"systemd.services"
|
"systemd.services"
|
||||||
"environment.gnome3.packageSet"
|
|
||||||
"kde.extraPackages"
|
"kde.extraPackages"
|
||||||
];
|
];
|
||||||
excludeOptions = list:
|
excludeOptions = list:
|
||||||
|
|||||||
@@ -6,12 +6,15 @@ let
|
|||||||
cfg = config.amazonImage;
|
cfg = config.amazonImage;
|
||||||
in {
|
in {
|
||||||
|
|
||||||
imports =
|
imports = [ ../../../modules/virtualisation/amazon-image.nix ];
|
||||||
[ ../../../modules/installer/cd-dvd/channel.nix
|
|
||||||
../../../modules/virtualisation/amazon-image.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
options.amazonImage = {
|
options.amazonImage = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The name of the generated derivation";
|
||||||
|
default = "nixos-disk-image";
|
||||||
|
};
|
||||||
|
|
||||||
contents = mkOption {
|
contents = mkOption {
|
||||||
example = literalExample ''
|
example = literalExample ''
|
||||||
[ { source = pkgs.memtest86 + "/memtest.bin";
|
[ { source = pkgs.memtest86 + "/memtest.bin";
|
||||||
@@ -25,15 +28,26 @@ in {
|
|||||||
generated image. Glob patterns work.
|
generated image. Glob patterns work.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sizeMB = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = if config.ec2.hvm then 2048 else 8192;
|
||||||
|
description = "The size in MB of the image";
|
||||||
|
};
|
||||||
|
|
||||||
|
format = mkOption {
|
||||||
|
type = types.enum [ "raw" "qcow2" "vpc" ];
|
||||||
|
default = "qcow2";
|
||||||
|
description = "The image format to output";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config.system.build.amazonImage = import ../../../lib/make-disk-image.nix {
|
config.system.build.amazonImage = import ../../../lib/make-disk-image.nix {
|
||||||
inherit lib config;
|
inherit lib config;
|
||||||
inherit (cfg) contents;
|
inherit (cfg) contents format name;
|
||||||
pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
|
pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
|
||||||
partitioned = config.ec2.hvm;
|
partitioned = config.ec2.hvm;
|
||||||
diskSize = if config.ec2.hvm then 2048 else 8192;
|
diskSize = cfg.sizeMB;
|
||||||
format = "qcow2";
|
|
||||||
configFile = pkgs.writeText "configuration.nix"
|
configFile = pkgs.writeText "configuration.nix"
|
||||||
''
|
''
|
||||||
{
|
{
|
||||||
@@ -44,5 +58,4 @@ in {
|
|||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ mkdir -p $stateDir
|
|||||||
rm -f ec2-amis.nix
|
rm -f ec2-amis.nix
|
||||||
|
|
||||||
types="hvm"
|
types="hvm"
|
||||||
stores="ebs s3"
|
stores="ebs"
|
||||||
regions="eu-west-1 eu-west-2 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ca-central-1 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1"
|
regions="eu-west-1 eu-west-2 eu-central-1 us-east-1 us-east-2 us-west-1 us-west-2 ca-central-1 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 ap-south-1"
|
||||||
|
|
||||||
for type in $types; do
|
for type in $types; do
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# nix-build '<nixpkgs/nixos>' -A config.system.build.novaImage --arg configuration "{ imports = [ ./nixos/maintainers/scripts/openstack/nova-image.nix ]; }"
|
||||||
|
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|||||||
@@ -30,14 +30,15 @@ with lib;
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
config = {
|
config = mkIf config.environment.enableDebugInfo {
|
||||||
|
|
||||||
# FIXME: currently disabled because /lib is already in
|
# FIXME: currently disabled because /lib is already in
|
||||||
# environment.pathsToLink, and we can't have both.
|
# environment.pathsToLink, and we can't have both.
|
||||||
#environment.pathsToLink = [ "/lib/debug/.build-id" ];
|
#environment.pathsToLink = [ "/lib/debug/.build-id" ];
|
||||||
|
|
||||||
environment.extraOutputsToInstall =
|
environment.extraOutputsToInstall = [ "debug" ];
|
||||||
optional config.environment.enableDebugInfo "debug";
|
|
||||||
|
environment.variables.NIX_DEBUG_INFO_DIRS = [ "/run/current-system/sw/lib/debug" ];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user