Merge remote-tracking branch 'upstream/master' into fix-darwin-bootstrap-cmds
This commit is contained in:
commit
49da4548b1
@ -1,8 +0,0 @@
|
||||
;;; Directory Local Variables
|
||||
;;; For more information see (info "(emacs) Directory Variables")
|
||||
|
||||
((nil
|
||||
(bug-reference-bug-regexp . "\\(\\(?:[Ii]ssue \\|[Ff]ixe[ds] \\|[Rr]esolve[ds]? \\|[Cc]lose[ds]? \\|[Pp]\\(?:ull [Rr]equest\\|[Rr]\\) \\|(\\)#\\([0-9]+\\))?\\)")
|
||||
(bug-reference-url-format . "https://github.com/NixOS/nixpkgs/issues/%s"))
|
||||
(nix-mode
|
||||
(tab-width . 2)))
|
37
.github/CODEOWNERS
vendored
37
.github/CODEOWNERS
vendored
@ -12,7 +12,7 @@
|
||||
|
||||
# Libraries
|
||||
/lib @edolstra @nbp
|
||||
/lib/systems @nbp @ericson2314
|
||||
/lib/systems @nbp @ericson2314 @matthewbauer
|
||||
/lib/generators.nix @edolstra @nbp @Profpatsch
|
||||
/lib/debug.nix @edolstra @nbp @Profpatsch
|
||||
|
||||
@ -20,9 +20,11 @@
|
||||
/default.nix @nbp
|
||||
/pkgs/top-level/default.nix @nbp @Ericson2314
|
||||
/pkgs/top-level/impure.nix @nbp @Ericson2314
|
||||
/pkgs/top-level/stage.nix @nbp @Ericson2314
|
||||
/pkgs/stdenv/generic @Ericson2314
|
||||
/pkgs/stdenv/cross @Ericson2314
|
||||
/pkgs/top-level/stage.nix @nbp @Ericson2314 @matthewbauer
|
||||
/pkgs/top-level/splice.nix @Ericson2314 @matthewbauer
|
||||
/pkgs/top-level/release-cross.nix @Ericson2314 @matthewbauer
|
||||
/pkgs/stdenv/generic @Ericson2314 @matthewbauer
|
||||
/pkgs/stdenv/cross @Ericson2314 @matthewbauer
|
||||
/pkgs/build-support/cc-wrapper @Ericson2314 @orivej
|
||||
/pkgs/build-support/bintools-wrapper @Ericson2314 @orivej
|
||||
/pkgs/build-support/setup-hooks @Ericson2314
|
||||
@ -45,6 +47,9 @@
|
||||
/nixos/doc/manual/man-nixos-option.xml @nbp
|
||||
/nixos/modules/installer/tools/nixos-option.sh @nbp
|
||||
|
||||
# NixOS modules
|
||||
/nixos/modules @Infinisil
|
||||
|
||||
# Python-related code and docs
|
||||
/maintainers/scripts/update-python-libraries @FRidh
|
||||
/pkgs/top-level/python-packages.nix @FRidh
|
||||
@ -74,6 +79,14 @@
|
||||
/pkgs/stdenv/darwin @NixOS/darwin-maintainers
|
||||
/pkgs/os-specific/darwin @NixOS/darwin-maintainers
|
||||
|
||||
# C compilers
|
||||
/pkgs/development/compilers/gcc @matthewbauer
|
||||
/pkgs/development/compilers/llvm @matthewbauer
|
||||
|
||||
# Compatibility stuff
|
||||
/pkgs/top-level/unix-tools.nix @matthewbauer
|
||||
/pkgs/development/tools/xcbuild @matthewbauer
|
||||
|
||||
# Beam-related (Erlang, Elixir, LFE, etc)
|
||||
/pkgs/development/beam-modules @gleber
|
||||
/pkgs/development/interpreters/erlang @gleber
|
||||
@ -97,3 +110,19 @@
|
||||
/pkgs/desktops/plasma-5 @ttuegel
|
||||
/pkgs/development/libraries/kde-frameworks @ttuegel
|
||||
/pkgs/development/libraries/qt-5 @ttuegel
|
||||
|
||||
# PostgreSQL and related stuff
|
||||
/pkgs/servers/sql/postgresql @thoughtpolice
|
||||
/nixos/modules/services/databases/postgresql.xml @thoughtpolice
|
||||
/nixos/modules/services/databases/postgresql.nix @thoughtpolice
|
||||
/nixos/tests/postgresql.nix @thoughtpolice
|
||||
|
||||
# Dhall
|
||||
/pkgs/development/dhall-modules @Gabriel439 @Profpatsch
|
||||
/pkgs/development/interpreters/dhall @Gabriel439 @Profpatsch
|
||||
|
||||
# Idris
|
||||
/pkgs/development/idris-modules @Infinisil
|
||||
|
||||
# Bazel
|
||||
/pkgs/development/tools/build-managers/bazel @mboes @Profpatsch
|
||||
|
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@ -20,6 +20,8 @@ under the terms of [COPYING](../COPYING), which is an MIT-like license.
|
||||
(Motivation for change. Additional information.)
|
||||
```
|
||||
|
||||
For consistency, there should not be a period at the end of the commit message's summary line (the first line of the commit message).
|
||||
|
||||
Examples:
|
||||
|
||||
* nginx: init at 2.0.1
|
||||
|
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -14,6 +14,7 @@
|
||||
- [ ] 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/`)
|
||||
- [ ] Determined the impact on package closure size (by running `nix path-info -S` before and after)
|
||||
- [ ] Assured whether relevant documentation is up to date
|
||||
- [ ] Fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md).
|
||||
|
||||
---
|
||||
|
9
COPYING
9
COPYING
@ -18,12 +18,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
======================================================================
|
||||
|
||||
Note: the license above does not apply to the packages built by the
|
||||
Nix Packages collection, merely to the package descriptions (i.e., Nix
|
||||
expressions, build scripts, etc.). It also might not apply to patches
|
||||
included in Nixpkgs, which may be derivative works of the packages to
|
||||
which they apply. The aforementioned artifacts are all covered by the
|
||||
licenses of the respective packages.
|
||||
|
16
README.md
16
README.md
@ -12,15 +12,15 @@ 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
|
||||
custom changes on top of one of the channels, e.g. `nixos-18.03` for the latest
|
||||
custom changes on top of one of the channels, e.g. `nixos-18.09` for the latest
|
||||
release and `nixos-unstable` for the latest successful build of master:
|
||||
|
||||
```
|
||||
% git remote update channels
|
||||
% git rebase channels/nixos-18.03
|
||||
% git rebase channels/nixos-18.09
|
||||
```
|
||||
|
||||
For pull-requests, please rebase onto nixpkgs `master`.
|
||||
For pull requests, please rebase onto nixpkgs `master`.
|
||||
|
||||
[NixOS](https://nixos.org/nixos/) Linux distribution source code is located inside
|
||||
`nixos/` folder.
|
||||
@ -31,11 +31,17 @@ For pull-requests, please rebase onto nixpkgs `master`.
|
||||
* [Manual (NixOS)](https://nixos.org/nixos/manual/)
|
||||
* [Community maintained wiki](https://nixos.wiki/)
|
||||
* [Continuous package builds for unstable/master](https://hydra.nixos.org/jobset/nixos/trunk-combined)
|
||||
* [Continuous package builds for 18.03 release](https://hydra.nixos.org/jobset/nixos/release-18.03)
|
||||
* [Continuous package builds for 18.09 release](https://hydra.nixos.org/jobset/nixos/release-18.09)
|
||||
* [Tests for unstable/master](https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
|
||||
* [Tests for 18.03 release](https://hydra.nixos.org/job/nixos/release-18.03/tested#tabs-constituents)
|
||||
* [Tests for 18.09 release](https://hydra.nixos.org/job/nixos/release-18.09/tested#tabs-constituents)
|
||||
|
||||
Communication:
|
||||
|
||||
* [Discourse Forum](https://discourse.nixos.org/)
|
||||
* [IRC - #nixos on freenode.net](irc://irc.freenode.net/#nixos)
|
||||
|
||||
Note: MIT license does not apply to the packages built by Nixpkgs, merely to
|
||||
the package descriptions (Nix expressions, build scripts, and so on). It also
|
||||
might not apply to patches included in Nixpkgs, which may be derivative works
|
||||
of the packages to which they apply. The aforementioned artifacts are all
|
||||
covered by the licenses of the respective packages.
|
||||
|
@ -18,7 +18,7 @@ if ! builtins ? nixVersion || builtins.compareVersions requiredVersion builtins.
|
||||
|
||||
For more information, please see the NixOS release notes at
|
||||
https://nixos.org/nixos/manual or locally at
|
||||
${toString ./doc/manual/release-notes}.
|
||||
${toString ./nixos/doc/manual/release-notes}.
|
||||
|
||||
If you need further help, see https://nixos.org/nixos/support.html
|
||||
''
|
||||
|
1
doc/.gitignore
vendored
1
doc/.gitignore
vendored
@ -4,3 +4,4 @@
|
||||
out
|
||||
manual-full.xml
|
||||
highlightjs
|
||||
functions/library/locations.xml
|
||||
|
@ -19,7 +19,7 @@ fix-misc-xml:
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f ${MD_TARGETS} .version manual-full.xml
|
||||
rm -f ${MD_TARGETS} .version manual-full.xml functions/library/locations.xml
|
||||
rm -rf ./out/ ./highlightjs
|
||||
|
||||
.PHONY: validate
|
||||
@ -69,13 +69,17 @@ highlightjs:
|
||||
cp -r "$$HIGHLIGHTJS/loader.js" highlightjs/
|
||||
|
||||
|
||||
manual-full.xml: ${MD_TARGETS} .version *.xml
|
||||
manual-full.xml: ${MD_TARGETS} .version functions/library/locations.xml *.xml **/*.xml **/**/*.xml
|
||||
xmllint --nonet --xinclude --noxincludenode manual.xml --output manual-full.xml
|
||||
|
||||
.version:
|
||||
nix-instantiate --eval \
|
||||
-E '(import ../lib).version' > .version
|
||||
|
||||
functions/library/locations.xml:
|
||||
nix-build ./lib-function-locations.nix \
|
||||
--out-link ./functions/library/locations.xml
|
||||
|
||||
%.section.xml: %.section.md
|
||||
pandoc $^ -w docbook+smart \
|
||||
-f markdown+smart \
|
||||
|
@ -56,25 +56,30 @@ foo { arg = ...; }
|
||||
or list elements should be aligned:
|
||||
<programlisting>
|
||||
# A long list.
|
||||
list =
|
||||
[ elem1
|
||||
elem2
|
||||
elem3
|
||||
];
|
||||
list = [
|
||||
elem1
|
||||
elem2
|
||||
elem3
|
||||
];
|
||||
|
||||
# A long attribute set.
|
||||
attrs =
|
||||
{ attr1 = short_expr;
|
||||
attr2 =
|
||||
if true then big_expr else big_expr;
|
||||
};
|
||||
|
||||
# Alternatively:
|
||||
attrs = {
|
||||
attr1 = short_expr;
|
||||
attr2 =
|
||||
if true then big_expr else big_expr;
|
||||
};
|
||||
|
||||
# Combined
|
||||
listOfAttrs = [
|
||||
{
|
||||
attr1 = 3;
|
||||
attr2 = "fff";
|
||||
}
|
||||
{
|
||||
attr1 = 5;
|
||||
attr2 = "ggg";
|
||||
}
|
||||
];
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
@ -191,6 +196,23 @@ args.stdenv.mkDerivation (args // {
|
||||
<section xml:id="sec-package-naming">
|
||||
<title>Package naming</title>
|
||||
|
||||
<para>
|
||||
The key words
|
||||
<emphasis>must</emphasis>,
|
||||
<emphasis>must not</emphasis>,
|
||||
<emphasis>required</emphasis>,
|
||||
<emphasis>shall</emphasis>,
|
||||
<emphasis>shall not</emphasis>,
|
||||
<emphasis>should</emphasis>,
|
||||
<emphasis>should not</emphasis>,
|
||||
<emphasis>recommended</emphasis>,
|
||||
<emphasis>may</emphasis>,
|
||||
and <emphasis>optional</emphasis> in this section
|
||||
are to be interpreted as described in
|
||||
<link xlink:href="https://tools.ietf.org/html/rfc2119">RFC 2119</link>.
|
||||
Only <emphasis>emphasized</emphasis> words are to be interpreted in this way.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In Nixpkgs, there are generally three different names associated with a
|
||||
package:
|
||||
@ -231,14 +253,15 @@ args.stdenv.mkDerivation (args // {
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Generally, try to stick to the upstream package name.
|
||||
The <literal>name</literal> attribute <emphasis>should</emphasis>
|
||||
be identical to the upstream package name.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Don’t use uppercase letters in the <literal>name</literal> attribute
|
||||
— e.g., <literal>"mplayer-1.0rc2"</literal> instead of
|
||||
<literal>"MPlayer-1.0rc2"</literal>.
|
||||
The <literal>name</literal> attribute <emphasis>must not</emphasis>
|
||||
contain uppercase letters — e.g., <literal>"mplayer-1.0rc2"</literal>
|
||||
instead of <literal>"MPlayer-1.0rc2"</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
@ -252,14 +275,14 @@ args.stdenv.mkDerivation (args // {
|
||||
<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
|
||||
(fetched) commit. The date must be in <literal>"YYYY-MM-DD"</literal>
|
||||
(fetched) commit. The date <emphasis>must</emphasis> be in <literal>"YYYY-MM-DD"</literal>
|
||||
format. Also append <literal>"unstable"</literal> to the name - e.g.,
|
||||
<literal>"pkgname-unstable-2014-09-23"</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Dashes in the package name should be preserved in new variable names,
|
||||
Dashes in the package name <emphasis>should</emphasis> be preserved in new variable names,
|
||||
rather than converted to underscores or camel cased — e.g.,
|
||||
<varname>http-parser</varname> instead of <varname>http_parser</varname>
|
||||
or <varname>httpParser</varname>. The hyphenated style is preferred in
|
||||
@ -268,7 +291,7 @@ args.stdenv.mkDerivation (args // {
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If there are multiple versions of a package, this should be reflected in
|
||||
If there are multiple versions of a package, this <emphasis>should</emphasis> be reflected in
|
||||
the variable names in <filename>all-packages.nix</filename>, e.g.
|
||||
<varname>json-c-0-9</varname> and <varname>json-c-0-11</varname>. If
|
||||
there is an obvious “default” version, make an attribute like
|
||||
@ -842,9 +865,12 @@ src = fetchFromGitHub {
|
||||
owner = "NixOS";
|
||||
repo = "nix";
|
||||
rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
|
||||
sha256 = "04yri911rj9j19qqqn6m82266fl05pz98inasni0vxr1cf1gdgv9";
|
||||
sha256 = "1i2yxndxb6yc9l6c99pypbd92lfq5aac4klq7y2v93c9qvx2cgpc";
|
||||
}
|
||||
</programlisting>
|
||||
Find the value to put as <literal>sha256</literal> by running
|
||||
<literal>nix run -f '<nixpkgs>' nix-prefetch-github -c nix-prefetch-github --rev 1f795f9f44607cc5bec70d1300150bfefcef2aae NixOS nix</literal>
|
||||
or <literal>nix-prefetch-url --unpack https://github.com/NixOS/nix/archive/1f795f9f44607cc5bec70d1300150bfefcef2aae.tar.gz</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
@ -132,7 +132,7 @@
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
The difference between an a package being unsupported on some system and
|
||||
The difference between a package being unsupported on some system and
|
||||
being broken is admittedly a bit fuzzy. If a program
|
||||
<emphasis>ought</emphasis> to work on a certain platform, but doesn't, the
|
||||
platform should be included in <literal>meta.platforms</literal>, but marked
|
||||
@ -175,11 +175,12 @@
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
A more useful example, the following configuration allows only allows
|
||||
flash player and visual studio code:
|
||||
For a more useful example, try the following. This configuration
|
||||
only allows unfree packages named flash player and visual studio
|
||||
code:
|
||||
<programlisting>
|
||||
{
|
||||
allowUnfreePredicate = (pkg: elem (builtins.parseDrvName pkg.name).name [ "flashplayer" "vscode" ]);
|
||||
allowUnfreePredicate = (pkg: builtins.elem (builtins.parseDrvName pkg.name).name [ "flashplayer" "vscode" ]);
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
@ -286,8 +287,8 @@
|
||||
|
||||
<para>
|
||||
You can define a function called <varname>packageOverrides</varname> in your
|
||||
local <filename>~/.config/nixpkgs/config.nix</filename> to override nix
|
||||
packages. It must be a function that takes pkgs as an argument and return
|
||||
local <filename>~/.config/nixpkgs/config.nix</filename> to override Nix
|
||||
packages. It must be a function that takes pkgs as an argument and returns a
|
||||
modified set of packages.
|
||||
<programlisting>
|
||||
{
|
||||
@ -325,7 +326,7 @@
|
||||
};
|
||||
};
|
||||
}
|
||||
</screen>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
To install it into our environment, you can just run <literal>nix-env -iA
|
||||
@ -347,7 +348,7 @@
|
||||
};
|
||||
};
|
||||
}
|
||||
</screen>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
<literal>pathsToLink</literal> tells Nixpkgs to only link the paths listed
|
||||
@ -383,7 +384,7 @@
|
||||
};
|
||||
};
|
||||
}
|
||||
</screen>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
This provides us with some useful documentation for using our packages.
|
||||
@ -395,15 +396,15 @@
|
||||
{
|
||||
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 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
|
||||
mkdir -p $out/etc/profile.d
|
||||
cp ${myProfile} $out/etc/profile.d/my-profile.sh
|
||||
'')
|
||||
aspell
|
||||
bc
|
||||
@ -421,7 +422,7 @@ cp ${myProfile} $out/etc/profile.d/my-profile.sh
|
||||
};
|
||||
};
|
||||
}
|
||||
</screen>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
For this to work fully, you must also have this script sourced when you are
|
||||
@ -438,7 +439,7 @@ if [ -d $HOME/.nix-profile/etc/profile.d ]; then
|
||||
fi
|
||||
done
|
||||
fi
|
||||
</screen>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
Now just run <literal>source $HOME/.profile</literal> and you can starting
|
||||
@ -459,16 +460,16 @@ fi
|
||||
{
|
||||
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
|
||||
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
|
||||
mkdir -p $out/etc/profile.d
|
||||
cp ${myProfile} $out/etc/profile.d/my-profile.sh
|
||||
'')
|
||||
aspell
|
||||
bc
|
||||
@ -485,17 +486,17 @@ cp ${myProfile} $out/etc/profile.d/my-profile.sh
|
||||
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
|
||||
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>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
<literal>postBuild</literal> tells Nixpkgs to run a command after building
|
||||
|
@ -6,17 +6,17 @@
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>
|
||||
"Cross-compilation" means compiling a program on one machine for another
|
||||
type of machine. For example, a typical use of cross compilation is to
|
||||
compile programs for embedded devices. These devices often don't have the
|
||||
computing power and memory to compile their own programs. One might think
|
||||
that cross-compilation is a fairly niche concern, but there are advantages
|
||||
to being rigorous about distinguishing build-time vs run-time environments
|
||||
even when one is developing and deploying on the same machine. Nixpkgs is
|
||||
increasingly adopting the opinion that packages should be written with
|
||||
cross-compilation in mind, and nixpkgs should evaluate in a similar way (by
|
||||
minimizing cross-compilation-specific special cases) whether or not one is
|
||||
cross-compiling.
|
||||
"Cross-compilation" means compiling a program on one machine for another type
|
||||
of machine. For example, a typical use of cross-compilation is to compile
|
||||
programs for embedded devices. These devices often don't have the computing
|
||||
power and memory to compile their own programs. One might think that
|
||||
cross-compilation is a fairly niche concern. However, there are significant
|
||||
advantages to rigorously distinguishing between build-time and run-time
|
||||
environments! This applies even when one is developing and deploying on the
|
||||
same machine. Nixpkgs is increasingly adopting the opinion that packages
|
||||
should be written with cross-compilation in mind, and nixpkgs should evaluate
|
||||
in a similar way (by minimizing cross-compilation-specific special cases)
|
||||
whether or not one is cross-compiling.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -34,22 +34,23 @@
|
||||
<title>Platform parameters</title>
|
||||
|
||||
<para>
|
||||
Nixpkgs follows the
|
||||
<link xlink:href="https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html">common
|
||||
historical convention of GNU autoconf</link> of distinguishing between 3
|
||||
types of platform: <wordasword>build</wordasword>,
|
||||
<wordasword>host</wordasword>, and <wordasword>target</wordasword>. In
|
||||
summary, <wordasword>build</wordasword> is the platform on which a package
|
||||
is being built, <wordasword>host</wordasword> is the platform on which it
|
||||
is to run. The third attribute, <wordasword>target</wordasword>, is
|
||||
relevant only for certain specific compilers and build tools.
|
||||
Nixpkgs follows the <link
|
||||
xlink:href="https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html">conventions
|
||||
of GNU autoconf</link>. We distinguish between 3 types of platforms when
|
||||
building a derivation: <wordasword>build</wordasword>,
|
||||
<wordasword>host</wordasword>, and <wordasword>target</wordasword>. In
|
||||
summary, <wordasword>build</wordasword> is the platform on which a package
|
||||
is being built, <wordasword>host</wordasword> is the platform on which it
|
||||
will run. The third attribute, <wordasword>target</wordasword>, is relevant
|
||||
only for certain specific compilers and build tools.
|
||||
</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>. They are always defined as attributes in
|
||||
the standard environment. That means one can access them like:
|
||||
names <literal>buildPlatform</literal>, <literal>hostPlatform</literal>,
|
||||
and <literal>targetPlatform</literal>. They are always defined as
|
||||
attributes in the standard environment. That means one can access them
|
||||
like:
|
||||
<programlisting>{ stdenv, fooDep, barDep, .. }: ...stdenv.buildPlatform...</programlisting>
|
||||
.
|
||||
</para>
|
||||
@ -63,7 +64,7 @@
|
||||
<para>
|
||||
The "build platform" is the platform on which a package is built. Once
|
||||
someone has a built package, or pre-built binary package, the build
|
||||
platform should not matter and be safe to ignore.
|
||||
platform should not matter and can be ignored.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -93,11 +94,11 @@
|
||||
<para>
|
||||
The build process of certain compilers is written in such a way that the
|
||||
compiler resulting from a single build can itself only produce binaries
|
||||
for a single platform. The task specifying this single "target platform"
|
||||
is thus pushed to build time of the compiler. The root cause of this
|
||||
mistake is often that the compiler (which will be run on the host) and
|
||||
the the standard library/runtime (which will be run on the target) are
|
||||
built by a single build process.
|
||||
for a single platform. The task of specifying this single "target
|
||||
platform" is thus pushed to build time of the compiler. The root cause of
|
||||
this that the compiler (which will be run on the host) and the standard
|
||||
library/runtime (which will be run on the target) are built by a single
|
||||
build process.
|
||||
</para>
|
||||
<para>
|
||||
There is no fundamental need to think about a single target ahead of
|
||||
@ -134,8 +135,10 @@
|
||||
<para>
|
||||
This is a two-component shorthand for the platform. Examples of this
|
||||
would be "x86_64-darwin" and "i686-linux"; see
|
||||
<literal>lib.systems.doubles</literal> for more. This format isn't very
|
||||
standard, but has built-in support in Nix, such as the
|
||||
<literal>lib.systems.doubles</literal> for more. The first component
|
||||
corresponds to the CPU architecture of the platform and the second to the
|
||||
operating system of the platform (<literal>[cpu]-[os]</literal>). This
|
||||
format has built-in support in Nix, such as the
|
||||
<varname>builtins.currentSystem</varname> impure string.
|
||||
</para>
|
||||
</listitem>
|
||||
@ -146,12 +149,13 @@
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This is a 3- or 4- component shorthand for the platform. Examples of
|
||||
this would be "x86_64-unknown-linux-gnu" and "aarch64-apple-darwin14".
|
||||
This is a standard format called the "LLVM target triple", as they are
|
||||
pioneered by LLVM and traditionally just used for the
|
||||
<varname>targetPlatform</varname>. This format is strictly more
|
||||
informative than the "Nix host double", as the previous format could
|
||||
This is a 3- or 4- component shorthand for the platform. Examples of this
|
||||
would be <literal>x86_64-unknown-linux-gnu</literal> and
|
||||
<literal>aarch64-apple-darwin14</literal>. This is a standard format
|
||||
called the "LLVM target triple", as they are pioneered by LLVM. In the
|
||||
4-part form, this corresponds to
|
||||
<literal>[cpu]-[vendor]-[os]-[abi]</literal>. This format is strictly
|
||||
more informative than the "Nix host double", as the previous format could
|
||||
analogously be termed. This needs a better name than
|
||||
<varname>config</varname>!
|
||||
</para>
|
||||
@ -163,12 +167,11 @@
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
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>. [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.
|
||||
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>. See
|
||||
<literal>lib.systems.parse</literal> for the exact
|
||||
representation.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -192,7 +195,7 @@
|
||||
<listitem>
|
||||
<para>
|
||||
These predicates are defined in <literal>lib.systems.inspect</literal>,
|
||||
and slapped on every platform. They are superior to the ones in
|
||||
and slapped onto 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>
|
||||
@ -220,7 +223,7 @@
|
||||
|
||||
<para>
|
||||
In this section we explore the relationship between both runtime and
|
||||
buildtime dependencies and the 3 Autoconf platforms.
|
||||
build-time dependencies and the 3 Autoconf platforms.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -248,17 +251,17 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Some examples will probably make this clearer. If a package is being built
|
||||
with a <literal>(build, host, target)</literal> platform triple of
|
||||
<literal>(foo, bar, bar)</literal>, then its build-time dependencies would
|
||||
have a triple of <literal>(foo, foo, bar)</literal>, and <emphasis>those
|
||||
packages'</emphasis> build-time dependencies would have triple of
|
||||
<literal>(foo, foo, foo)</literal>. In other words, it should take two
|
||||
"rounds" of following build-time dependency edges before one reaches a
|
||||
fixed point where, by the sliding window principle, the platform triple no
|
||||
longer changes. Indeed, this happens with cross compilation, where only
|
||||
rounds of native dependencies starting with the second necessarily coincide
|
||||
with native packages.
|
||||
Some examples will make this clearer. If a package is being built with a
|
||||
<literal>(build, host, target)</literal> platform triple of <literal>(foo,
|
||||
bar, bar)</literal>, then its build-time dependencies would have a triple of
|
||||
<literal>(foo, foo, bar)</literal>, and <emphasis>those packages'</emphasis>
|
||||
build-time dependencies would have a triple of <literal>(foo, foo,
|
||||
foo)</literal>. In other words, it should take two "rounds" of following
|
||||
build-time dependency edges before one reaches a fixed point where, by the
|
||||
sliding window principle, the platform triple no longer changes. Indeed,
|
||||
this happens with cross-compilation, where only rounds of native
|
||||
dependencies starting with the second necessarily coincide with native
|
||||
packages.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
@ -270,23 +273,23 @@
|
||||
</note>
|
||||
|
||||
<para>
|
||||
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. 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 six (<emphasis>gasp</emphasis>) attributes used for
|
||||
specifying dependencies as documented in
|
||||
<xref linkend="ssec-stdenv-dependencies"/>. 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. 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.
|
||||
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. 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 six (<emphasis>gasp</emphasis>) attributes used for specifying
|
||||
dependencies as documented in <xref linkend="ssec-stdenv-dependencies"/>. 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. 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.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
@ -304,11 +307,11 @@
|
||||
<title>Cross packaging cookbook</title>
|
||||
|
||||
<para>
|
||||
Some frequently problems when packaging for cross compilation are good to
|
||||
just spell and answer. Ideally the information above is exhaustive, so this
|
||||
section cannot provide any new information, but its ludicrous and cruel to
|
||||
expect everyone to spend effort working through the interaction of many
|
||||
features just to figure out the same answer to the same common problem.
|
||||
Some frequently encountered problems when packaging for cross-compilation
|
||||
should be answered here. Ideally, the information above is exhaustive, so
|
||||
this section cannot provide any new information, but it is ludicrous and
|
||||
cruel to expect everyone to spend effort working through the interaction of
|
||||
many features just to figure out the same answer to the same common problem.
|
||||
Feel free to add to this list!
|
||||
</para>
|
||||
|
||||
@ -363,17 +366,9 @@
|
||||
<section xml:id="sec-cross-usage">
|
||||
<title>Cross-building packages</title>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
More information needs to moved from the old wiki, especially
|
||||
<link xlink:href="https://nixos.org/wiki/CrossCompiling" />, for this
|
||||
section.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
Nixpkgs can be instantiated with <varname>localSystem</varname> alone, in
|
||||
which case there is no cross compiling and everything is built by and for
|
||||
which case there is no cross-compiling and everything is built by and for
|
||||
that system, or also with <varname>crossSystem</varname>, in which case
|
||||
packages run on the latter, but all building happens on the former. Both
|
||||
parameters take the same schema as the 3 (build, host, and target) platforms
|
||||
@ -390,7 +385,7 @@ nix-build <nixpkgs> --arg crossSystem '(import <nixpkgs/lib>).system
|
||||
Eventually we would like to make these platform examples an unnecessary
|
||||
convenience so that
|
||||
<programlisting>
|
||||
nix-build <nixpkgs> --arg crossSystem.config '<arch>-<os>-<vendor>-<abi>' -A whatever</programlisting>
|
||||
nix-build <nixpkgs> --arg crossSystem '{ config = "<arch>-<os>-<vendor>-<abi>"; }' -A whatever</programlisting>
|
||||
works in the vast majority of cases. The problem today is dependencies on
|
||||
other sorts of configuration which aren't given proper defaults. We rely on
|
||||
the examples to crudely to set those configuration parameters in some
|
||||
@ -439,15 +434,14 @@ nix-build <nixpkgs> --arg crossSystem.config '<arch>-<os>-<
|
||||
build plan or package set. A simple "build vs deploy" dichotomy is adequate:
|
||||
the sliding window principle described in the previous section shows how to
|
||||
interpolate between the these two "end points" to get the 3 platform triple
|
||||
for each bootstrapping stage. That means for any package a given package
|
||||
set, even those not bound on the top level but only reachable via
|
||||
dependencies or <varname>buildPackages</varname>, the three platforms will
|
||||
be defined as one of <varname>localSystem</varname> or
|
||||
<varname>crossSystem</varname>, with the former replacing the latter as one
|
||||
traverses build-time dependencies. A last simple difference then is
|
||||
<varname>crossSystem</varname> should be null when one doesn't want to
|
||||
cross-compile, while the <varname>*Platform</varname>s are always non-null.
|
||||
<varname>localSystem</varname> is always non-null.
|
||||
for each bootstrapping stage. That means for any package a given package set,
|
||||
even those not bound on the top level but only reachable via dependencies or
|
||||
<varname>buildPackages</varname>, the three platforms will be defined as one
|
||||
of <varname>localSystem</varname> or <varname>crossSystem</varname>, with the
|
||||
former replacing the latter as one traverses build-time dependencies. A last
|
||||
simple difference is that <varname>crossSystem</varname> should be null when
|
||||
one doesn't want to cross-compile, while the <varname>*Platform</varname>s
|
||||
are always non-null. <varname>localSystem</varname> is always non-null.
|
||||
</para>
|
||||
</section>
|
||||
<!--============================================================-->
|
||||
@ -460,14 +454,14 @@ nix-build <nixpkgs> --arg crossSystem.config '<arch>-<os>-<
|
||||
|
||||
<note>
|
||||
<para>
|
||||
If one explores nixpkgs, they will see derivations with names like
|
||||
<literal>gccCross</literal>. Such <literal>*Cross</literal> derivations is
|
||||
a holdover from before we properly distinguished between the host and
|
||||
target platforms —the derivation with "Cross" in the name covered the
|
||||
<literal>build = host != target</literal> case, while the other covered the
|
||||
<literal>host = target</literal>, with build platform the same or not based
|
||||
on whether one was using its <literal>.nativeDrv</literal> or
|
||||
<literal>.crossDrv</literal>. This ugliness will disappear soon.
|
||||
If one explores Nixpkgs, they will see derivations with names like
|
||||
<literal>gccCross</literal>. Such <literal>*Cross</literal> derivations is a
|
||||
holdover from before we properly distinguished between the host and target
|
||||
platforms—the derivation with "Cross" in the name covered the <literal>build
|
||||
= host != target</literal> case, while the other covered the <literal>host =
|
||||
target</literal>, with build platform the same or not based on whether one
|
||||
was using its <literal>.nativeDrv</literal> or <literal>.crossDrv</literal>.
|
||||
This ugliness will disappear soon.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
|
@ -1,6 +1,7 @@
|
||||
{ pkgs ? (import ./.. { }), nixpkgs ? { }}:
|
||||
let
|
||||
pkgs = import ./.. { };
|
||||
lib = pkgs.lib;
|
||||
locationsXml = import ./lib-function-locations.nix { inherit pkgs nixpkgs; };
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "nixpkgs-manual";
|
||||
@ -29,6 +30,8 @@ pkgs.stdenv.mkDerivation {
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
rm -rf ./functions/library/locations.xml
|
||||
ln -s ${locationsXml} ./functions/library/locations.xml
|
||||
echo ${lib.version} > .version
|
||||
'';
|
||||
|
||||
|
@ -1,799 +1,17 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="chap-functions">
|
||||
xml:id="chap-functions">
|
||||
<title>Functions reference</title>
|
||||
<para>
|
||||
The nixpkgs repository has several utility functions to manipulate Nix
|
||||
expressions.
|
||||
</para>
|
||||
<section xml:id="sec-overrides">
|
||||
<title>Overriding</title>
|
||||
|
||||
<para>
|
||||
Sometimes one wants to override parts of <literal>nixpkgs</literal>, e.g.
|
||||
derivation attributes, the results of derivations or even the whole package
|
||||
set.
|
||||
</para>
|
||||
|
||||
<section xml:id="sec-pkg-override">
|
||||
<title><pkg>.override</title>
|
||||
|
||||
<para>
|
||||
The function <varname>override</varname> is usually available for all the
|
||||
derivations in the nixpkgs expression (<varname>pkgs</varname>).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is used to override the arguments passed to a function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usages:
|
||||
<programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting>
|
||||
<programlisting>import pkgs.path { overlays = [ (self: super: {
|
||||
foo = super.foo.override { barSupport = true ; };
|
||||
})]};</programlisting>
|
||||
<programlisting>mypkg = pkgs.callPackage ./mypkg.nix {
|
||||
mydep = pkgs.mydep.override { ... };
|
||||
}</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the first example, <varname>pkgs.foo</varname> is the result of a
|
||||
function call with some default arguments, usually a derivation. Using
|
||||
<varname>pkgs.foo.override</varname> will call the same function with the
|
||||
given new arguments.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-pkg-overrideAttrs">
|
||||
<title><pkg>.overrideAttrs</title>
|
||||
|
||||
<para>
|
||||
The function <varname>overrideAttrs</varname> allows overriding the
|
||||
attribute set passed to a <varname>stdenv.mkDerivation</varname> call,
|
||||
producing a new derivation based on the original one. This function is
|
||||
available on all derivations produced by the
|
||||
<varname>stdenv.mkDerivation</varname> function, which is most packages in
|
||||
the nixpkgs expression <varname>pkgs</varname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usage:
|
||||
<programlisting>helloWithDebug = pkgs.hello.overrideAttrs (oldAttrs: rec {
|
||||
separateDebugInfo = true;
|
||||
});</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the above example, the <varname>separateDebugInfo</varname> attribute is
|
||||
overridden to be true, thus building debug info for
|
||||
<varname>helloWithDebug</varname>, while all other attributes will be
|
||||
retained from the original <varname>hello</varname> package.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The argument <varname>oldAttrs</varname> is conventionally used to refer to
|
||||
the attr set originally passed to <varname>stdenv.mkDerivation</varname>.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Note that <varname>separateDebugInfo</varname> is processed only by the
|
||||
<varname>stdenv.mkDerivation</varname> function, not the generated, raw
|
||||
Nix derivation. Thus, using <varname>overrideDerivation</varname> will not
|
||||
work in this case, as it overrides only the attributes of the final
|
||||
derivation. It is for this reason that <varname>overrideAttrs</varname>
|
||||
should be preferred in (almost) all cases to
|
||||
<varname>overrideDerivation</varname>, i.e. to allow using
|
||||
<varname>sdenv.mkDerivation</varname> to process input arguments, as well
|
||||
as the fact that it is easier to use (you can use the same attribute names
|
||||
you see in your Nix code, instead of the ones generated (e.g.
|
||||
<varname>buildInputs</varname> vs <varname>nativeBuildInputs</varname>,
|
||||
and involves less typing.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-pkg-overrideDerivation">
|
||||
<title><pkg>.overrideDerivation</title>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
You should prefer <varname>overrideAttrs</varname> in almost all cases,
|
||||
see its documentation for the reasons why.
|
||||
<varname>overrideDerivation</varname> is not deprecated and will continue
|
||||
to work, but is less nice to use and does not have as many abilities as
|
||||
<varname>overrideAttrs</varname>.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
Do not use this function in Nixpkgs as it evaluates a Derivation before
|
||||
modifying it, which breaks package abstraction and removes error-checking
|
||||
of function arguments. In addition, this evaluation-per-function
|
||||
application incurs a performance penalty, which can become a problem if
|
||||
many overrides are used. It is only intended for ad-hoc customisation,
|
||||
such as in <filename>~/.config/nixpkgs/config.nix</filename>.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<para>
|
||||
The function <varname>overrideDerivation</varname> creates a new derivation
|
||||
based on an existing one by overriding the original's attributes with the
|
||||
attribute set produced by the specified function. This function is
|
||||
available on all derivations defined using the
|
||||
<varname>makeOverridable</varname> function. Most standard
|
||||
derivation-producing functions, such as
|
||||
<varname>stdenv.mkDerivation</varname>, are defined using this function,
|
||||
which means most packages in the nixpkgs expression,
|
||||
<varname>pkgs</varname>, have this function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usage:
|
||||
<programlisting>mySed = pkgs.gnused.overrideDerivation (oldAttrs: {
|
||||
name = "sed-4.2.2-pre";
|
||||
src = fetchurl {
|
||||
url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
|
||||
sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
|
||||
};
|
||||
patches = [];
|
||||
});</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the above example, the <varname>name</varname>, <varname>src</varname>,
|
||||
and <varname>patches</varname> of the derivation will be overridden, while
|
||||
all other attributes will be retained from the original derivation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The argument <varname>oldAttrs</varname> is used to refer to the attribute
|
||||
set of the original derivation.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
A package's attributes are evaluated *before* being modified by the
|
||||
<varname>overrideDerivation</varname> function. For example, the
|
||||
<varname>name</varname> attribute reference in <varname>url =
|
||||
"mirror://gnu/hello/${name}.tar.gz";</varname> is filled-in *before* the
|
||||
<varname>overrideDerivation</varname> function modifies the attribute set.
|
||||
This means that overriding the <varname>name</varname> attribute, in this
|
||||
example, *will not* change the value of the <varname>url</varname>
|
||||
attribute. Instead, we need to override both the <varname>name</varname>
|
||||
*and* <varname>url</varname> attributes.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-lib-makeOverridable">
|
||||
<title>lib.makeOverridable</title>
|
||||
|
||||
<para>
|
||||
The function <varname>lib.makeOverridable</varname> is used to make the
|
||||
result of a function easily customizable. This utility only makes sense for
|
||||
functions that accept an argument set and return an attribute set.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usage:
|
||||
<programlisting>f = { a, b }: { result = a+b; }
|
||||
c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The variable <varname>c</varname> is the value of the <varname>f</varname>
|
||||
function applied with some default arguments. Hence the value of
|
||||
<varname>c.result</varname> is <literal>3</literal>, in this example.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The variable <varname>c</varname> however also has some additional
|
||||
functions, like <link linkend="sec-pkg-override">c.override</link> which
|
||||
can be used to override the default arguments. In this example the value of
|
||||
<varname>(c.override { a = 4; }).result</varname> is 6.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="sec-generators">
|
||||
<title>Generators</title>
|
||||
|
||||
<para>
|
||||
Generators are functions that create file formats from nix data structures,
|
||||
e. g. for configuration files. There are generators available for:
|
||||
<literal>INI</literal>, <literal>JSON</literal> and <literal>YAML</literal>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All generators follow a similar call interface: <code>generatorName
|
||||
configFunctions data</code>, where <literal>configFunctions</literal> is an
|
||||
attrset of user-defined functions that format nested parts of the content.
|
||||
They each have common defaults, so often they do not need to be set
|
||||
manually. An example is <code>mkSectionName ? (name: libStr.escape [ "[" "]"
|
||||
] name)</code> from the <literal>INI</literal> generator. It receives the
|
||||
name of a section and sanitizes it. The default
|
||||
<literal>mkSectionName</literal> escapes <literal>[</literal> and
|
||||
<literal>]</literal> with a backslash.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Generators can be fine-tuned to produce exactly the file format required by
|
||||
your application/service. One example is an INI-file format which uses
|
||||
<literal>: </literal> as separator, the strings
|
||||
<literal>"yes"</literal>/<literal>"no"</literal> as boolean values and
|
||||
requires all string values to be quoted:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
with lib;
|
||||
let
|
||||
customToINI = generators.toINI {
|
||||
# specifies how to format a key/value pair
|
||||
mkKeyValue = generators.mkKeyValueDefault {
|
||||
# specifies the generated string for a subset of nix values
|
||||
mkValueString = v:
|
||||
if v == true then ''"yes"''
|
||||
else if v == false then ''"no"''
|
||||
else if isString v then ''"${v}"''
|
||||
# and delegats all other values to the default generator
|
||||
else generators.mkValueStringDefault {} v;
|
||||
} ":";
|
||||
};
|
||||
|
||||
# the INI file can now be given as plain old nix values
|
||||
in customToINI {
|
||||
main = {
|
||||
pushinfo = true;
|
||||
autopush = false;
|
||||
host = "localhost";
|
||||
port = 42;
|
||||
};
|
||||
mergetool = {
|
||||
merge = "diff3";
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
This will produce the following INI file as nix string:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
[main]
|
||||
autopush:"no"
|
||||
host:"localhost"
|
||||
port:42
|
||||
pushinfo:"yes"
|
||||
str\:ange:"very::strange"
|
||||
|
||||
[mergetool]
|
||||
merge:"diff3"
|
||||
</programlisting>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Nix store paths can be converted to strings by enclosing a derivation
|
||||
attribute like so: <code>"${drv}"</code>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
Detailed documentation for each generator can be found in
|
||||
<literal>lib/generators.nix</literal>.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="sec-debug">
|
||||
<title>Debugging Nix Expressions</title>
|
||||
|
||||
<para>
|
||||
Nix is a unityped, dynamic language, this means every value can potentially
|
||||
appear anywhere. Since it is also non-strict, evaluation order and what
|
||||
ultimately is evaluated might surprise you. Therefore it is important to be
|
||||
able to debug nix expressions.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the <literal>lib/debug.nix</literal> file you will find a number of
|
||||
functions that help (pretty-)printing values while evaluation is runnnig.
|
||||
You can even specify how deep these values should be printed recursively,
|
||||
and transform them on the fly. Please consult the docstrings in
|
||||
<literal>lib/debug.nix</literal> for usage information.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="sec-fhs-environments">
|
||||
<title>buildFHSUserEnv</title>
|
||||
|
||||
<para>
|
||||
<function>buildFHSUserEnv</function> provides a way to build and run
|
||||
FHS-compatible lightweight sandboxes. It creates an isolated root with bound
|
||||
<filename>/nix/store</filename>, so its footprint in terms of disk space
|
||||
needed is quite small. This allows one to run software which is hard or
|
||||
unfeasible to patch for NixOS -- 3rd-party source trees with FHS
|
||||
assumptions, games distributed as tarballs, software with integrity checking
|
||||
and/or external self-updated binaries. It uses Linux namespaces feature to
|
||||
create temporary lightweight environments which are destroyed after all
|
||||
child processes exit, without root user rights requirement. Accepted
|
||||
arguments are:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>name</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Environment name.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>targetPkgs</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Packages to be installed for the main host's architecture (i.e. x86_64 on
|
||||
x86_64 installations). Along with libraries binaries are also installed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>multiPkgs</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Packages to be installed for all architectures supported by a host (i.e.
|
||||
i686 and x86_64 on x86_64 installations). Only libraries are installed by
|
||||
default.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraBuildCommands</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Additional commands to be executed for finalizing the directory
|
||||
structure.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraBuildCommandsMulti</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Like <literal>extraBuildCommands</literal>, but executed only on multilib
|
||||
architectures.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraOutputsToInstall</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Additional derivation outputs to be linked for both target and
|
||||
multi-architecture packages.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraInstallCommands</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Additional commands to be executed for finalizing the derivation with
|
||||
runner script.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>runScript</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A command that would be executed inside the sandbox and passed all the
|
||||
command line arguments. It defaults to <literal>bash</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
One can create a simple environment using a <literal>shell.nix</literal>
|
||||
like that:
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
(pkgs.buildFHSUserEnv {
|
||||
name = "simple-x11-env";
|
||||
targetPkgs = pkgs: (with pkgs;
|
||||
[ udev
|
||||
alsaLib
|
||||
]) ++ (with pkgs.xorg;
|
||||
[ libX11
|
||||
libXcursor
|
||||
libXrandr
|
||||
]);
|
||||
multiPkgs = pkgs: (with pkgs;
|
||||
[ udev
|
||||
alsaLib
|
||||
]);
|
||||
runScript = "bash";
|
||||
}).env
|
||||
]]></programlisting>
|
||||
|
||||
<para>
|
||||
Running <literal>nix-shell</literal> would then drop you into a shell with
|
||||
these libraries and binaries available. You can use this to run
|
||||
closed-source applications which expect FHS structure without hassles:
|
||||
simply change <literal>runScript</literal> to the application path, e.g.
|
||||
<filename>./bin/start.sh</filename> -- relative paths are supported.
|
||||
</para>
|
||||
</section>
|
||||
<xi:include href="shell.section.xml" />
|
||||
<section xml:id="sec-pkgs-dockerTools">
|
||||
<title>pkgs.dockerTools</title>
|
||||
|
||||
<para>
|
||||
<varname>pkgs.dockerTools</varname> is a set of functions for creating and
|
||||
manipulating Docker images according to the
|
||||
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#docker-image-specification-v120">
|
||||
Docker Image Specification v1.2.0 </link>. Docker itself is not used to
|
||||
perform any of the operations done by these functions.
|
||||
</para>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
The <varname>dockerTools</varname> API is unstable and may be subject to
|
||||
backwards-incompatible changes in the future.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-buildImage">
|
||||
<title>buildImage</title>
|
||||
|
||||
<para>
|
||||
This function is analogous to the <command>docker build</command> command,
|
||||
in that can used to build a Docker-compatible repository tarball containing
|
||||
a single image with one or multiple layers. As such, the result is suitable
|
||||
for being loaded in Docker with <command>docker load</command>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The parameters of <varname>buildImage</varname> with relative example
|
||||
values are described below:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-buildImage'>
|
||||
<title>Docker build</title>
|
||||
<programlisting>
|
||||
buildImage {
|
||||
name = "redis"; <co xml:id='ex-dockerTools-buildImage-1' />
|
||||
tag = "latest"; <co xml:id='ex-dockerTools-buildImage-2' />
|
||||
|
||||
fromImage = someBaseImage; <co xml:id='ex-dockerTools-buildImage-3' />
|
||||
fromImageName = null; <co xml:id='ex-dockerTools-buildImage-4' />
|
||||
fromImageTag = "latest"; <co xml:id='ex-dockerTools-buildImage-5' />
|
||||
|
||||
contents = pkgs.redis; <co xml:id='ex-dockerTools-buildImage-6' />
|
||||
runAsRoot = '' <co xml:id='ex-dockerTools-buildImage-runAsRoot' />
|
||||
#!${stdenv.shell}
|
||||
mkdir -p /data
|
||||
'';
|
||||
|
||||
config = { <co xml:id='ex-dockerTools-buildImage-8' />
|
||||
Cmd = [ "/bin/redis-server" ];
|
||||
WorkingDir = "/data";
|
||||
Volumes = {
|
||||
"/data" = {};
|
||||
};
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
The above example will build a Docker image <literal>redis/latest</literal>
|
||||
from the given base image. Loading and running this image in Docker results
|
||||
in <literal>redis-server</literal> being started automatically.
|
||||
</para>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs='ex-dockerTools-buildImage-1'>
|
||||
<para>
|
||||
<varname>name</varname> specifies the name of the resulting image. This
|
||||
is the only required argument for <varname>buildImage</varname>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-2'>
|
||||
<para>
|
||||
<varname>tag</varname> specifies the tag of the resulting image. By
|
||||
default it's <literal>null</literal>, which indicates that the nix output
|
||||
hash will be used as tag.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-3'>
|
||||
<para>
|
||||
<varname>fromImage</varname> is the repository tarball containing the
|
||||
base image. It must be a valid Docker image, such as exported by
|
||||
<command>docker save</command>. By default it's <literal>null</literal>,
|
||||
which can be seen as equivalent to <literal>FROM scratch</literal> of a
|
||||
<filename>Dockerfile</filename>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-4'>
|
||||
<para>
|
||||
<varname>fromImageName</varname> can be used to further specify the base
|
||||
image within the repository, in case it contains multiple images. By
|
||||
default it's <literal>null</literal>, in which case
|
||||
<varname>buildImage</varname> will peek the first image available in the
|
||||
repository.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-5'>
|
||||
<para>
|
||||
<varname>fromImageTag</varname> can be used to further specify the tag of
|
||||
the base image within the repository, in case an image contains multiple
|
||||
tags. By default it's <literal>null</literal>, in which case
|
||||
<varname>buildImage</varname> will peek the first tag available for the
|
||||
base image.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-6'>
|
||||
<para>
|
||||
<varname>contents</varname> is a derivation that will be copied in the
|
||||
new layer of the resulting image. This can be similarly seen as
|
||||
<command>ADD contents/ /</command> in a <filename>Dockerfile</filename>.
|
||||
By default it's <literal>null</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-runAsRoot'>
|
||||
<para>
|
||||
<varname>runAsRoot</varname> is a bash script that will run as root in an
|
||||
environment that overlays the existing layers of the base image with the
|
||||
new resulting layer, including the previously copied
|
||||
<varname>contents</varname> derivation. This can be similarly seen as
|
||||
<command>RUN ...</command> in a <filename>Dockerfile</filename>.
|
||||
<note>
|
||||
<para>
|
||||
Using this parameter requires the <literal>kvm</literal> device to be
|
||||
available.
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-8'>
|
||||
<para>
|
||||
<varname>config</varname> is used to specify the configuration of the
|
||||
containers that will be started off the built image in Docker. The
|
||||
available options are listed in the
|
||||
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions">
|
||||
Docker Image Specification v1.2.0 </link>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
|
||||
<para>
|
||||
After the new layer has been created, its closure (to which
|
||||
<varname>contents</varname>, <varname>config</varname> and
|
||||
<varname>runAsRoot</varname> contribute) will be copied in the layer
|
||||
itself. Only new dependencies that are not already in the existing layers
|
||||
will be copied.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
At the end of the process, only one new single layer will be produced and
|
||||
added to the resulting image.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The resulting repository will only list the single image
|
||||
<varname>image/tag</varname>. In the case of
|
||||
<xref linkend='ex-dockerTools-buildImage'/> it would be
|
||||
<varname>redis/latest</varname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is possible to inspect the arguments with which an image was built using
|
||||
its <varname>buildArgs</varname> attribute.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
If you see errors similar to <literal>getProtocolByName: does not exist
|
||||
(no such protocol name: tcp)</literal> you may need to add
|
||||
<literal>pkgs.iana-etc</literal> to <varname>contents</varname>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
If you see errors similar to <literal>Error_Protocol ("certificate has
|
||||
unknown CA",True,UnknownCa)</literal> you may need to add
|
||||
<literal>pkgs.cacert</literal> to <varname>contents</varname>.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-fetchFromRegistry">
|
||||
<title>pullImage</title>
|
||||
|
||||
<para>
|
||||
This function is analogous to the <command>docker pull</command> command,
|
||||
in that can be used to pull a Docker image from a Docker registry. By
|
||||
default <link xlink:href="https://hub.docker.com/">Docker Hub</link> is
|
||||
used to pull images.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Its parameters are described in the example below:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-pullImage'>
|
||||
<title>Docker pull</title>
|
||||
<programlisting>
|
||||
pullImage {
|
||||
imageName = "nixos/nix"; <co xml:id='ex-dockerTools-pullImage-1' />
|
||||
imageDigest = "sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b"; <co xml:id='ex-dockerTools-pullImage-2' />
|
||||
finalImageTag = "1.11"; <co xml:id='ex-dockerTools-pullImage-3' />
|
||||
sha256 = "0mqjy3zq2v6rrhizgb9nvhczl87lcfphq9601wcprdika2jz7qh8"; <co xml:id='ex-dockerTools-pullImage-4' />
|
||||
os = "linux"; <co xml:id='ex-dockerTools-pullImage-5' />
|
||||
arch = "x86_64"; <co xml:id='ex-dockerTools-pullImage-6' />
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs='ex-dockerTools-pullImage-1'>
|
||||
<para>
|
||||
<varname>imageName</varname> specifies the name of the image to be
|
||||
downloaded, which can also include the registry namespace (e.g.
|
||||
<literal>nixos</literal>). This argument is required.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-2'>
|
||||
<para>
|
||||
<varname>imageDigest</varname> specifies the digest of the image to be
|
||||
downloaded. Skopeo can be used to get the digest of an image, with its
|
||||
<varname>inspect</varname> subcommand. Since a given
|
||||
<varname>imageName</varname> may transparently refer to a manifest list
|
||||
of images which support multiple architectures and/or operating systems,
|
||||
supply the `--override-os` and `--override-arch` arguments to specify
|
||||
exactly which image you want. By default it will match the OS and
|
||||
architecture of the host the command is run on.
|
||||
<programlisting>
|
||||
$ nix-shell --packages skopeo jq --command "skopeo --override-os linux --override-arch x86_64 inspect docker://docker.io/nixos/nix:1.11 | jq -r '.Digest'"
|
||||
sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b
|
||||
</programlisting>
|
||||
This argument is required.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-3'>
|
||||
<para>
|
||||
<varname>finalImageTag</varname>, if specified, this is the tag of the
|
||||
image to be created. Note it is never used to fetch the image since we
|
||||
prefer to rely on the immutable digest ID. By default it's
|
||||
<literal>latest</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-4'>
|
||||
<para>
|
||||
<varname>sha256</varname> is the checksum of the whole fetched image.
|
||||
This argument is required.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-5'>
|
||||
<para>
|
||||
<varname>os</varname>, if specified, is the operating system of the
|
||||
fetched image. By default it's <literal>linux</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-6'>
|
||||
<para>
|
||||
<varname>arch</varname>, if specified, is the cpu architecture of the
|
||||
fetched image. By default it's <literal>x86_64</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-exportImage">
|
||||
<title>exportImage</title>
|
||||
|
||||
<para>
|
||||
This function is analogous to the <command>docker export</command> command,
|
||||
in that can used to flatten a Docker image that contains multiple layers.
|
||||
It is in fact the result of the merge of all the layers of the image. As
|
||||
such, the result is suitable for being imported in Docker with
|
||||
<command>docker import</command>.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Using this function requires the <literal>kvm</literal> device to be
|
||||
available.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
The parameters of <varname>exportImage</varname> are the following:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-exportImage'>
|
||||
<title>Docker export</title>
|
||||
<programlisting>
|
||||
exportImage {
|
||||
fromImage = someLayeredImage;
|
||||
fromImageName = null;
|
||||
fromImageTag = null;
|
||||
|
||||
name = someLayeredImage.name;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
The parameters relative to the base image have the same synopsis as
|
||||
described in <xref linkend='ssec-pkgs-dockerTools-buildImage'/>, except
|
||||
that <varname>fromImage</varname> is the only required argument in this
|
||||
case.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <varname>name</varname> argument is the name of the derivation output,
|
||||
which defaults to <varname>fromImage.name</varname>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-shadowSetup">
|
||||
<title>shadowSetup</title>
|
||||
|
||||
<para>
|
||||
This constant string is a helper for setting up the base files for managing
|
||||
users and groups, only if such files don't exist already. It is suitable
|
||||
for being used in a <varname>runAsRoot</varname>
|
||||
<xref linkend='ex-dockerTools-buildImage-runAsRoot'/> script for cases like
|
||||
in the example below:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-shadowSetup'>
|
||||
<title>Shadow base files</title>
|
||||
<programlisting>
|
||||
buildImage {
|
||||
name = "shadow-basic";
|
||||
|
||||
runAsRoot = ''
|
||||
#!${stdenv.shell}
|
||||
${shadowSetup}
|
||||
groupadd -r redis
|
||||
useradd -r -g redis redis
|
||||
mkdir /data
|
||||
chown redis:redis /data
|
||||
'';
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Creating base files like <literal>/etc/passwd</literal> or
|
||||
<literal>/etc/login.defs</literal> are necessary for shadow-utils to
|
||||
manipulate users and groups.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<xi:include href="functions/library.xml" />
|
||||
<xi:include href="functions/overrides.xml" />
|
||||
<xi:include href="functions/generators.xml" />
|
||||
<xi:include href="functions/debug.xml" />
|
||||
<xi:include href="functions/fhs-environments.xml" />
|
||||
<xi:include href="functions/shell.xml" />
|
||||
<xi:include href="functions/dockertools.xml" />
|
||||
</chapter>
|
||||
|
21
doc/functions/debug.xml
Normal file
21
doc/functions/debug.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="sec-debug">
|
||||
<title>Debugging Nix Expressions</title>
|
||||
|
||||
<para>
|
||||
Nix is a unityped, dynamic language, this means every value can potentially
|
||||
appear anywhere. Since it is also non-strict, evaluation order and what
|
||||
ultimately is evaluated might surprise you. Therefore it is important to be
|
||||
able to debug nix expressions.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the <literal>lib/debug.nix</literal> file you will find a number of
|
||||
functions that help (pretty-)printing values while evaluation is runnnig. You
|
||||
can even specify how deep these values should be printed recursively, and
|
||||
transform them on the fly. Please consult the docstrings in
|
||||
<literal>lib/debug.nix</literal> for usage information.
|
||||
</para>
|
||||
</section>
|
564
doc/functions/dockertools.xml
Normal file
564
doc/functions/dockertools.xml
Normal file
@ -0,0 +1,564 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="sec-pkgs-dockerTools">
|
||||
<title>pkgs.dockerTools</title>
|
||||
|
||||
<para>
|
||||
<varname>pkgs.dockerTools</varname> is a set of functions for creating and
|
||||
manipulating Docker images according to the
|
||||
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#docker-image-specification-v120">
|
||||
Docker Image Specification v1.2.0 </link>. Docker itself is not used to
|
||||
perform any of the operations done by these functions.
|
||||
</para>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
The <varname>dockerTools</varname> API is unstable and may be subject to
|
||||
backwards-incompatible changes in the future.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-buildImage">
|
||||
<title>buildImage</title>
|
||||
|
||||
<para>
|
||||
This function is analogous to the <command>docker build</command> command,
|
||||
in that can used to build a Docker-compatible repository tarball containing
|
||||
a single image with one or multiple layers. As such, the result is suitable
|
||||
for being loaded in Docker with <command>docker load</command>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The parameters of <varname>buildImage</varname> with relative example values
|
||||
are described below:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-buildImage'>
|
||||
<title>Docker build</title>
|
||||
<programlisting>
|
||||
buildImage {
|
||||
name = "redis"; <co xml:id='ex-dockerTools-buildImage-1' />
|
||||
tag = "latest"; <co xml:id='ex-dockerTools-buildImage-2' />
|
||||
|
||||
fromImage = someBaseImage; <co xml:id='ex-dockerTools-buildImage-3' />
|
||||
fromImageName = null; <co xml:id='ex-dockerTools-buildImage-4' />
|
||||
fromImageTag = "latest"; <co xml:id='ex-dockerTools-buildImage-5' />
|
||||
|
||||
contents = pkgs.redis; <co xml:id='ex-dockerTools-buildImage-6' />
|
||||
runAsRoot = '' <co xml:id='ex-dockerTools-buildImage-runAsRoot' />
|
||||
#!${stdenv.shell}
|
||||
mkdir -p /data
|
||||
'';
|
||||
|
||||
config = { <co xml:id='ex-dockerTools-buildImage-8' />
|
||||
Cmd = [ "/bin/redis-server" ];
|
||||
WorkingDir = "/data";
|
||||
Volumes = {
|
||||
"/data" = {};
|
||||
};
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
The above example will build a Docker image <literal>redis/latest</literal>
|
||||
from the given base image. Loading and running this image in Docker results
|
||||
in <literal>redis-server</literal> being started automatically.
|
||||
</para>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs='ex-dockerTools-buildImage-1'>
|
||||
<para>
|
||||
<varname>name</varname> specifies the name of the resulting image. This is
|
||||
the only required argument for <varname>buildImage</varname>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-2'>
|
||||
<para>
|
||||
<varname>tag</varname> specifies the tag of the resulting image. By
|
||||
default it's <literal>null</literal>, which indicates that the nix output
|
||||
hash will be used as tag.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-3'>
|
||||
<para>
|
||||
<varname>fromImage</varname> is the repository tarball containing the base
|
||||
image. It must be a valid Docker image, such as exported by
|
||||
<command>docker save</command>. By default it's <literal>null</literal>,
|
||||
which can be seen as equivalent to <literal>FROM scratch</literal> of a
|
||||
<filename>Dockerfile</filename>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-4'>
|
||||
<para>
|
||||
<varname>fromImageName</varname> can be used to further specify the base
|
||||
image within the repository, in case it contains multiple images. By
|
||||
default it's <literal>null</literal>, in which case
|
||||
<varname>buildImage</varname> will peek the first image available in the
|
||||
repository.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-5'>
|
||||
<para>
|
||||
<varname>fromImageTag</varname> can be used to further specify the tag of
|
||||
the base image within the repository, in case an image contains multiple
|
||||
tags. By default it's <literal>null</literal>, in which case
|
||||
<varname>buildImage</varname> will peek the first tag available for the
|
||||
base image.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-6'>
|
||||
<para>
|
||||
<varname>contents</varname> is a derivation that will be copied in the new
|
||||
layer of the resulting image. This can be similarly seen as <command>ADD
|
||||
contents/ /</command> in a <filename>Dockerfile</filename>. By default
|
||||
it's <literal>null</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-runAsRoot'>
|
||||
<para>
|
||||
<varname>runAsRoot</varname> is a bash script that will run as root in an
|
||||
environment that overlays the existing layers of the base image with the
|
||||
new resulting layer, including the previously copied
|
||||
<varname>contents</varname> derivation. This can be similarly seen as
|
||||
<command>RUN ...</command> in a <filename>Dockerfile</filename>.
|
||||
<note>
|
||||
<para>
|
||||
Using this parameter requires the <literal>kvm</literal> device to be
|
||||
available.
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-buildImage-8'>
|
||||
<para>
|
||||
<varname>config</varname> is used to specify the configuration of the
|
||||
containers that will be started off the built image in Docker. The
|
||||
available options are listed in the
|
||||
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions">
|
||||
Docker Image Specification v1.2.0 </link>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
|
||||
<para>
|
||||
After the new layer has been created, its closure (to which
|
||||
<varname>contents</varname>, <varname>config</varname> and
|
||||
<varname>runAsRoot</varname> contribute) will be copied in the layer itself.
|
||||
Only new dependencies that are not already in the existing layers will be
|
||||
copied.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
At the end of the process, only one new single layer will be produced and
|
||||
added to the resulting image.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The resulting repository will only list the single image
|
||||
<varname>image/tag</varname>. In the case of
|
||||
<xref linkend='ex-dockerTools-buildImage'/> it would be
|
||||
<varname>redis/latest</varname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is possible to inspect the arguments with which an image was built using
|
||||
its <varname>buildArgs</varname> attribute.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
If you see errors similar to <literal>getProtocolByName: does not exist (no
|
||||
such protocol name: tcp)</literal> you may need to add
|
||||
<literal>pkgs.iana-etc</literal> to <varname>contents</varname>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
If you see errors similar to <literal>Error_Protocol ("certificate has
|
||||
unknown CA",True,UnknownCa)</literal> you may need to add
|
||||
<literal>pkgs.cacert</literal> to <varname>contents</varname>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<example xml:id="example-pkgs-dockerTools-buildImage-creation-date">
|
||||
<title>Impurely Defining a Docker Layer's Creation Date</title>
|
||||
<para>
|
||||
By default <function>buildImage</function> will use a static date of one
|
||||
second past the UNIX Epoch. This allows <function>buildImage</function> to
|
||||
produce binary reproducible images. When listing images with
|
||||
<command>docker list images</command>, the newly created images will be
|
||||
listed like this:
|
||||
</para>
|
||||
<screen><![CDATA[
|
||||
$ docker image list
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
hello latest 08c791c7846e 48 years ago 25.2MB
|
||||
]]></screen>
|
||||
<para>
|
||||
You can break binary reproducibility but have a sorted, meaningful
|
||||
<literal>CREATED</literal> column by setting <literal>created</literal> to
|
||||
<literal>now</literal>.
|
||||
</para>
|
||||
<programlisting><![CDATA[
|
||||
pkgs.dockerTools.buildImage {
|
||||
name = "hello";
|
||||
tag = "latest";
|
||||
created = "now";
|
||||
contents = pkgs.hello;
|
||||
|
||||
config.Cmd = [ "/bin/hello" ];
|
||||
}
|
||||
]]></programlisting>
|
||||
<para>
|
||||
and now the Docker CLI will display a reasonable date and sort the images
|
||||
as expected:
|
||||
<screen><![CDATA[
|
||||
$ docker image list
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
hello latest de2bf4786de6 About a minute ago 25.2MB
|
||||
]]></screen>
|
||||
however, the produced images will not be binary reproducible.
|
||||
</para>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-buildLayeredImage">
|
||||
<title>buildLayeredImage</title>
|
||||
|
||||
<para>
|
||||
Create a Docker image with many of the store paths being on their own layer
|
||||
to improve sharing between images.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>name</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The name of the resulting image.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>tag</varname> <emphasis>optional</emphasis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Tag of the generated image.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Default:</emphasis> the output path's hash
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>contents</varname> <emphasis>optional</emphasis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Top level paths in the container. Either a single derivation, or a list
|
||||
of derivations.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Default:</emphasis> <literal>[]</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>config</varname> <emphasis>optional</emphasis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Run-time configuration of the container. A full list of the options are
|
||||
available at in the
|
||||
<link xlink:href="https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions">
|
||||
Docker Image Specification v1.2.0 </link>.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Default:</emphasis> <literal>{}</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>created</varname> <emphasis>optional</emphasis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Date and time the layers were created. Follows the same
|
||||
<literal>now</literal> exception supported by
|
||||
<literal>buildImage</literal>.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Default:</emphasis> <literal>1970-01-01T00:00:01Z</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>maxLayers</varname> <emphasis>optional</emphasis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Maximum number of layers to create.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Default:</emphasis> <literal>24</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<section xml:id="dockerTools-buildLayeredImage-arg-contents">
|
||||
<title>Behavior of <varname>contents</varname> in the final image</title>
|
||||
|
||||
<para>
|
||||
Each path directly listed in <varname>contents</varname> will have a
|
||||
symlink in the root of the image.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For example:
|
||||
<programlisting><![CDATA[
|
||||
pkgs.dockerTools.buildLayeredImage {
|
||||
name = "hello";
|
||||
contents = [ pkgs.hello ];
|
||||
}
|
||||
]]></programlisting>
|
||||
will create symlinks for all the paths in the <literal>hello</literal>
|
||||
package:
|
||||
<screen><![CDATA[
|
||||
/bin/hello -> /nix/store/h1zb1padqbbb7jicsvkmrym3r6snphxg-hello-2.10/bin/hello
|
||||
/share/info/hello.info -> /nix/store/h1zb1padqbbb7jicsvkmrym3r6snphxg-hello-2.10/share/info/hello.info
|
||||
/share/locale/bg/LC_MESSAGES/hello.mo -> /nix/store/h1zb1padqbbb7jicsvkmrym3r6snphxg-hello-2.10/share/locale/bg/LC_MESSAGES/hello.mo
|
||||
]]></screen>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="dockerTools-buildLayeredImage-arg-config">
|
||||
<title>Automatic inclusion of <varname>config</varname> references</title>
|
||||
|
||||
<para>
|
||||
The closure of <varname>config</varname> is automatically included in the
|
||||
closure of the final image.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This allows you to make very simple Docker images with very little code.
|
||||
This container will start up and run <command>hello</command>:
|
||||
<programlisting><![CDATA[
|
||||
pkgs.dockerTools.buildLayeredImage {
|
||||
name = "hello";
|
||||
config.Cmd = [ "${pkgs.hello}/bin/hello" ];
|
||||
}
|
||||
]]></programlisting>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="dockerTools-buildLayeredImage-arg-maxLayers">
|
||||
<title>Adjusting <varname>maxLayers</varname></title>
|
||||
|
||||
<para>
|
||||
Increasing the <varname>maxLayers</varname> increases the number of layers
|
||||
which have a chance to be shared between different images.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Modern Docker installations support up to 128 layers, however older
|
||||
versions support as few as 42.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the produced image will not be extended by other Docker builds, it is
|
||||
safe to set <varname>maxLayers</varname> to <literal>128</literal>. However
|
||||
it will be impossible to extend the image further.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The first (<literal>maxLayers-2</literal>) most "popular" paths will have
|
||||
their own individual layers, then layer #<literal>maxLayers-1</literal>
|
||||
will contain all the remaining "unpopular" paths, and finally layer
|
||||
#<literal>maxLayers</literal> will contain the Image configuration.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Docker's Layers are not inherently ordered, they are content-addressable
|
||||
and are not explicitly layered until they are composed in to an Image.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-fetchFromRegistry">
|
||||
<title>pullImage</title>
|
||||
|
||||
<para>
|
||||
This function is analogous to the <command>docker pull</command> command, in
|
||||
that can be used to pull a Docker image from a Docker registry. By default
|
||||
<link xlink:href="https://hub.docker.com/">Docker Hub</link> is used to pull
|
||||
images.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Its parameters are described in the example below:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-pullImage'>
|
||||
<title>Docker pull</title>
|
||||
<programlisting>
|
||||
pullImage {
|
||||
imageName = "nixos/nix"; <co xml:id='ex-dockerTools-pullImage-1' />
|
||||
imageDigest = "sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b"; <co xml:id='ex-dockerTools-pullImage-2' />
|
||||
finalImageTag = "1.11"; <co xml:id='ex-dockerTools-pullImage-3' />
|
||||
sha256 = "0mqjy3zq2v6rrhizgb9nvhczl87lcfphq9601wcprdika2jz7qh8"; <co xml:id='ex-dockerTools-pullImage-4' />
|
||||
os = "linux"; <co xml:id='ex-dockerTools-pullImage-5' />
|
||||
arch = "x86_64"; <co xml:id='ex-dockerTools-pullImage-6' />
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs='ex-dockerTools-pullImage-1'>
|
||||
<para>
|
||||
<varname>imageName</varname> specifies the name of the image to be
|
||||
downloaded, which can also include the registry namespace (e.g.
|
||||
<literal>nixos</literal>). This argument is required.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-2'>
|
||||
<para>
|
||||
<varname>imageDigest</varname> specifies the digest of the image to be
|
||||
downloaded. Skopeo can be used to get the digest of an image, with its
|
||||
<varname>inspect</varname> subcommand. Since a given
|
||||
<varname>imageName</varname> may transparently refer to a manifest list of
|
||||
images which support multiple architectures and/or operating systems,
|
||||
supply the `--override-os` and `--override-arch` arguments to specify
|
||||
exactly which image you want. By default it will match the OS and
|
||||
architecture of the host the command is run on.
|
||||
<programlisting>
|
||||
$ nix-shell --packages skopeo jq --command "skopeo --override-os linux --override-arch x86_64 inspect docker://docker.io/nixos/nix:1.11 | jq -r '.Digest'"
|
||||
sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b
|
||||
</programlisting>
|
||||
This argument is required.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-3'>
|
||||
<para>
|
||||
<varname>finalImageTag</varname>, if specified, this is the tag of the
|
||||
image to be created. Note it is never used to fetch the image since we
|
||||
prefer to rely on the immutable digest ID. By default it's
|
||||
<literal>latest</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-4'>
|
||||
<para>
|
||||
<varname>sha256</varname> is the checksum of the whole fetched image. This
|
||||
argument is required.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-5'>
|
||||
<para>
|
||||
<varname>os</varname>, if specified, is the operating system of the
|
||||
fetched image. By default it's <literal>linux</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-dockerTools-pullImage-6'>
|
||||
<para>
|
||||
<varname>arch</varname>, if specified, is the cpu architecture of the
|
||||
fetched image. By default it's <literal>x86_64</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-exportImage">
|
||||
<title>exportImage</title>
|
||||
|
||||
<para>
|
||||
This function is analogous to the <command>docker export</command> command,
|
||||
in that can used to flatten a Docker image that contains multiple layers. It
|
||||
is in fact the result of the merge of all the layers of the image. As such,
|
||||
the result is suitable for being imported in Docker with <command>docker
|
||||
import</command>.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Using this function requires the <literal>kvm</literal> device to be
|
||||
available.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
The parameters of <varname>exportImage</varname> are the following:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-exportImage'>
|
||||
<title>Docker export</title>
|
||||
<programlisting>
|
||||
exportImage {
|
||||
fromImage = someLayeredImage;
|
||||
fromImageName = null;
|
||||
fromImageTag = null;
|
||||
|
||||
name = someLayeredImage.name;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
The parameters relative to the base image have the same synopsis as
|
||||
described in <xref linkend='ssec-pkgs-dockerTools-buildImage'/>, except that
|
||||
<varname>fromImage</varname> is the only required argument in this case.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <varname>name</varname> argument is the name of the derivation output,
|
||||
which defaults to <varname>fromImage.name</varname>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ssec-pkgs-dockerTools-shadowSetup">
|
||||
<title>shadowSetup</title>
|
||||
|
||||
<para>
|
||||
This constant string is a helper for setting up the base files for managing
|
||||
users and groups, only if such files don't exist already. It is suitable for
|
||||
being used in a <varname>runAsRoot</varname>
|
||||
<xref linkend='ex-dockerTools-buildImage-runAsRoot'/> script for cases like
|
||||
in the example below:
|
||||
</para>
|
||||
|
||||
<example xml:id='ex-dockerTools-shadowSetup'>
|
||||
<title>Shadow base files</title>
|
||||
<programlisting>
|
||||
buildImage {
|
||||
name = "shadow-basic";
|
||||
|
||||
runAsRoot = ''
|
||||
#!${stdenv.shell}
|
||||
${shadowSetup}
|
||||
groupadd -r redis
|
||||
useradd -r -g redis redis
|
||||
mkdir /data
|
||||
chown redis:redis /data
|
||||
'';
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Creating base files like <literal>/etc/passwd</literal> or
|
||||
<literal>/etc/login.defs</literal> are necessary for shadow-utils to
|
||||
manipulate users and groups.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
142
doc/functions/fhs-environments.xml
Normal file
142
doc/functions/fhs-environments.xml
Normal file
@ -0,0 +1,142 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="sec-fhs-environments">
|
||||
<title>buildFHSUserEnv</title>
|
||||
|
||||
<para>
|
||||
<function>buildFHSUserEnv</function> provides a way to build and run
|
||||
FHS-compatible lightweight sandboxes. It creates an isolated root with bound
|
||||
<filename>/nix/store</filename>, so its footprint in terms of disk space
|
||||
needed is quite small. This allows one to run software which is hard or
|
||||
unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions,
|
||||
games distributed as tarballs, software with integrity checking and/or
|
||||
external self-updated binaries. It uses Linux namespaces feature to create
|
||||
temporary lightweight environments which are destroyed after all child
|
||||
processes exit, without root user rights requirement. Accepted arguments are:
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>name</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Environment name.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>targetPkgs</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Packages to be installed for the main host's architecture (i.e. x86_64 on
|
||||
x86_64 installations). Along with libraries binaries are also installed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>multiPkgs</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Packages to be installed for all architectures supported by a host (i.e.
|
||||
i686 and x86_64 on x86_64 installations). Only libraries are installed by
|
||||
default.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraBuildCommands</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Additional commands to be executed for finalizing the directory structure.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraBuildCommandsMulti</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Like <literal>extraBuildCommands</literal>, but executed only on multilib
|
||||
architectures.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraOutputsToInstall</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Additional derivation outputs to be linked for both target and
|
||||
multi-architecture packages.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>extraInstallCommands</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Additional commands to be executed for finalizing the derivation with
|
||||
runner script.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<literal>runScript</literal>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A command that would be executed inside the sandbox and passed all the
|
||||
command line arguments. It defaults to <literal>bash</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
One can create a simple environment using a <literal>shell.nix</literal> like
|
||||
that:
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
(pkgs.buildFHSUserEnv {
|
||||
name = "simple-x11-env";
|
||||
targetPkgs = pkgs: (with pkgs;
|
||||
[ udev
|
||||
alsaLib
|
||||
]) ++ (with pkgs.xorg;
|
||||
[ libX11
|
||||
libXcursor
|
||||
libXrandr
|
||||
]);
|
||||
multiPkgs = pkgs: (with pkgs;
|
||||
[ udev
|
||||
alsaLib
|
||||
]);
|
||||
runScript = "bash";
|
||||
}).env
|
||||
]]></programlisting>
|
||||
|
||||
<para>
|
||||
Running <literal>nix-shell</literal> would then drop you into a shell with
|
||||
these libraries and binaries available. You can use this to run closed-source
|
||||
applications which expect FHS structure without hassles: simply change
|
||||
<literal>runScript</literal> to the application path, e.g.
|
||||
<filename>./bin/start.sh</filename> -- relative paths are supported.
|
||||
</para>
|
||||
</section>
|
89
doc/functions/generators.xml
Normal file
89
doc/functions/generators.xml
Normal file
@ -0,0 +1,89 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="sec-generators">
|
||||
<title>Generators</title>
|
||||
|
||||
<para>
|
||||
Generators are functions that create file formats from nix data structures,
|
||||
e. g. for configuration files. There are generators available for:
|
||||
<literal>INI</literal>, <literal>JSON</literal> and <literal>YAML</literal>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All generators follow a similar call interface: <code>generatorName
|
||||
configFunctions data</code>, where <literal>configFunctions</literal> is an
|
||||
attrset of user-defined functions that format nested parts of the content.
|
||||
They each have common defaults, so often they do not need to be set manually.
|
||||
An example is <code>mkSectionName ? (name: libStr.escape [ "[" "]" ]
|
||||
name)</code> from the <literal>INI</literal> generator. It receives the name
|
||||
of a section and sanitizes it. The default <literal>mkSectionName</literal>
|
||||
escapes <literal>[</literal> and <literal>]</literal> with a backslash.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Generators can be fine-tuned to produce exactly the file format required by
|
||||
your application/service. One example is an INI-file format which uses
|
||||
<literal>: </literal> as separator, the strings
|
||||
<literal>"yes"</literal>/<literal>"no"</literal> as boolean values and
|
||||
requires all string values to be quoted:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
with lib;
|
||||
let
|
||||
customToINI = generators.toINI {
|
||||
# specifies how to format a key/value pair
|
||||
mkKeyValue = generators.mkKeyValueDefault {
|
||||
# specifies the generated string for a subset of nix values
|
||||
mkValueString = v:
|
||||
if v == true then ''"yes"''
|
||||
else if v == false then ''"no"''
|
||||
else if isString v then ''"${v}"''
|
||||
# and delegats all other values to the default generator
|
||||
else generators.mkValueStringDefault {} v;
|
||||
} ":";
|
||||
};
|
||||
|
||||
# the INI file can now be given as plain old nix values
|
||||
in customToINI {
|
||||
main = {
|
||||
pushinfo = true;
|
||||
autopush = false;
|
||||
host = "localhost";
|
||||
port = 42;
|
||||
};
|
||||
mergetool = {
|
||||
merge = "diff3";
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
This will produce the following INI file as nix string:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
[main]
|
||||
autopush:"no"
|
||||
host:"localhost"
|
||||
port:42
|
||||
pushinfo:"yes"
|
||||
str\:ange:"very::strange"
|
||||
|
||||
[mergetool]
|
||||
merge:"diff3"
|
||||
</programlisting>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Nix store paths can be converted to strings by enclosing a derivation
|
||||
attribute like so: <code>"${drv}"</code>.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
Detailed documentation for each generator can be found in
|
||||
<literal>lib/generators.nix</literal>.
|
||||
</para>
|
||||
</section>
|
15
doc/functions/library.xml
Normal file
15
doc/functions/library.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="sec-functions-library">
|
||||
<title>Nixpkgs Library Functions</title>
|
||||
|
||||
<para>
|
||||
Nixpkgs provides a standard library at <varname>pkgs.lib</varname>, or
|
||||
through <code>import <nixpkgs/lib></code>.
|
||||
</para>
|
||||
|
||||
<xi:include href="./library/asserts.xml" />
|
||||
|
||||
<xi:include href="./library/attrsets.xml" />
|
||||
</section>
|
117
doc/functions/library/asserts.xml
Normal file
117
doc/functions/library/asserts.xml
Normal file
@ -0,0 +1,117 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="sec-functions-library-asserts">
|
||||
<title>Assert functions</title>
|
||||
|
||||
<section xml:id="function-library-lib.asserts.assertMsg">
|
||||
<title><function>lib.asserts.assertMsg</function></title>
|
||||
|
||||
<subtitle><literal>assertMsg :: Bool -> String -> Bool</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.asserts.assertMsg" />
|
||||
|
||||
<para>
|
||||
Print a trace message if <literal>pred</literal> is false.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Intended to be used to augment asserts with helpful error messages.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>pred</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Condition under which the <varname>msg</varname> should
|
||||
<emphasis>not</emphasis> be printed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>msg</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Message to print.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.asserts.assertMsg-example-false">
|
||||
<title>Printing when the predicate is false</title>
|
||||
<programlisting><![CDATA[
|
||||
assert lib.asserts.assertMsg ("foo" == "bar") "foo is not bar, silly"
|
||||
stderr> trace: foo is not bar, silly
|
||||
stderr> assert failed
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.asserts.assertOneOf">
|
||||
<title><function>lib.asserts.assertOneOf</function></title>
|
||||
|
||||
<subtitle><literal>assertOneOf :: String -> String ->
|
||||
StringList -> Bool</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.asserts.assertOneOf" />
|
||||
|
||||
<para>
|
||||
Specialized <function>asserts.assertMsg</function> for checking if
|
||||
<varname>val</varname> is one of the elements of <varname>xs</varname>.
|
||||
Useful for checking enums.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>name</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The name of the variable the user entered <varname>val</varname> into,
|
||||
for inclusion in the error message.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>val</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The value of what the user provided, to be compared against the values in
|
||||
<varname>xs</varname>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>xs</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The list of valid values.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.asserts.assertOneOf-example">
|
||||
<title>Ensuring a user provided a possible value</title>
|
||||
<programlisting><![CDATA[
|
||||
let sslLibrary = "bearssl";
|
||||
in lib.asserts.assertOneOf "sslLibrary" sslLibrary [ "openssl" "bearssl" ];
|
||||
=> false
|
||||
stderr> trace: sslLibrary must be one of "openssl", "libressl", but is: "bearssl"
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
</section>
|
1731
doc/functions/library/attrsets.xml
Normal file
1731
doc/functions/library/attrsets.xml
Normal file
File diff suppressed because it is too large
Load Diff
212
doc/functions/overrides.xml
Normal file
212
doc/functions/overrides.xml
Normal file
@ -0,0 +1,212 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="sec-overrides">
|
||||
<title>Overriding</title>
|
||||
|
||||
<para>
|
||||
Sometimes one wants to override parts of <literal>nixpkgs</literal>, e.g.
|
||||
derivation attributes, the results of derivations.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
These functions are used to make changes to packages, returning only single
|
||||
packages. <link xlink:href="#chap-overlays">Overlays</link>, on the other
|
||||
hand, can be used to combine the overridden packages across the entire
|
||||
package set of Nixpkgs.
|
||||
</para>
|
||||
|
||||
<section xml:id="sec-pkg-override">
|
||||
<title><pkg>.override</title>
|
||||
|
||||
<para>
|
||||
The function <varname>override</varname> is usually available for all the
|
||||
derivations in the nixpkgs expression (<varname>pkgs</varname>).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is used to override the arguments passed to a function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usages:
|
||||
<programlisting>pkgs.foo.override { arg1 = val1; arg2 = val2; ... }</programlisting>
|
||||
<!-- TODO: move below programlisting to a new section about extending and overlays
|
||||
and reference it
|
||||
-->
|
||||
<programlisting>
|
||||
import pkgs.path { overlays = [ (self: super: {
|
||||
foo = super.foo.override { barSupport = true ; };
|
||||
})]};
|
||||
</programlisting>
|
||||
<programlisting>
|
||||
mypkg = pkgs.callPackage ./mypkg.nix {
|
||||
mydep = pkgs.mydep.override { ... };
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the first example, <varname>pkgs.foo</varname> is the result of a
|
||||
function call with some default arguments, usually a derivation. Using
|
||||
<varname>pkgs.foo.override</varname> will call the same function with the
|
||||
given new arguments.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-pkg-overrideAttrs">
|
||||
<title><pkg>.overrideAttrs</title>
|
||||
|
||||
<para>
|
||||
The function <varname>overrideAttrs</varname> allows overriding the
|
||||
attribute set passed to a <varname>stdenv.mkDerivation</varname> call,
|
||||
producing a new derivation based on the original one. This function is
|
||||
available on all derivations produced by the
|
||||
<varname>stdenv.mkDerivation</varname> function, which is most packages in
|
||||
the nixpkgs expression <varname>pkgs</varname>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usage:
|
||||
<programlisting>
|
||||
helloWithDebug = pkgs.hello.overrideAttrs (oldAttrs: rec {
|
||||
separateDebugInfo = true;
|
||||
});
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the above example, the <varname>separateDebugInfo</varname> attribute is
|
||||
overridden to be true, thus building debug info for
|
||||
<varname>helloWithDebug</varname>, while all other attributes will be
|
||||
retained from the original <varname>hello</varname> package.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The argument <varname>oldAttrs</varname> is conventionally used to refer to
|
||||
the attr set originally passed to <varname>stdenv.mkDerivation</varname>.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Note that <varname>separateDebugInfo</varname> is processed only by the
|
||||
<varname>stdenv.mkDerivation</varname> function, not the generated, raw Nix
|
||||
derivation. Thus, using <varname>overrideDerivation</varname> will not work
|
||||
in this case, as it overrides only the attributes of the final derivation.
|
||||
It is for this reason that <varname>overrideAttrs</varname> should be
|
||||
preferred in (almost) all cases to <varname>overrideDerivation</varname>,
|
||||
i.e. to allow using <varname>stdenv.mkDerivation</varname> to process input
|
||||
arguments, as well as the fact that it is easier to use (you can use the
|
||||
same attribute names you see in your Nix code, instead of the ones
|
||||
generated (e.g. <varname>buildInputs</varname> vs
|
||||
<varname>nativeBuildInputs</varname>), and it involves less typing).
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-pkg-overrideDerivation">
|
||||
<title><pkg>.overrideDerivation</title>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
You should prefer <varname>overrideAttrs</varname> in almost all cases, see
|
||||
its documentation for the reasons why.
|
||||
<varname>overrideDerivation</varname> is not deprecated and will continue
|
||||
to work, but is less nice to use and does not have as many abilities as
|
||||
<varname>overrideAttrs</varname>.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
Do not use this function in Nixpkgs as it evaluates a Derivation before
|
||||
modifying it, which breaks package abstraction and removes error-checking
|
||||
of function arguments. In addition, this evaluation-per-function
|
||||
application incurs a performance penalty, which can become a problem if
|
||||
many overrides are used. It is only intended for ad-hoc customisation, such
|
||||
as in <filename>~/.config/nixpkgs/config.nix</filename>.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<para>
|
||||
The function <varname>overrideDerivation</varname> creates a new derivation
|
||||
based on an existing one by overriding the original's attributes with the
|
||||
attribute set produced by the specified function. This function is available
|
||||
on all derivations defined using the <varname>makeOverridable</varname>
|
||||
function. Most standard derivation-producing functions, such as
|
||||
<varname>stdenv.mkDerivation</varname>, are defined using this function,
|
||||
which means most packages in the nixpkgs expression,
|
||||
<varname>pkgs</varname>, have this function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usage:
|
||||
<programlisting>
|
||||
mySed = pkgs.gnused.overrideDerivation (oldAttrs: {
|
||||
name = "sed-4.2.2-pre";
|
||||
src = fetchurl {
|
||||
url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
|
||||
sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
|
||||
};
|
||||
patches = [];
|
||||
});
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the above example, the <varname>name</varname>, <varname>src</varname>,
|
||||
and <varname>patches</varname> of the derivation will be overridden, while
|
||||
all other attributes will be retained from the original derivation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The argument <varname>oldAttrs</varname> is used to refer to the attribute
|
||||
set of the original derivation.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
A package's attributes are evaluated *before* being modified by the
|
||||
<varname>overrideDerivation</varname> function. For example, the
|
||||
<varname>name</varname> attribute reference in <varname>url =
|
||||
"mirror://gnu/hello/${name}.tar.gz";</varname> is filled-in *before* the
|
||||
<varname>overrideDerivation</varname> function modifies the attribute set.
|
||||
This means that overriding the <varname>name</varname> attribute, in this
|
||||
example, *will not* change the value of the <varname>url</varname>
|
||||
attribute. Instead, we need to override both the <varname>name</varname>
|
||||
*and* <varname>url</varname> attributes.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-lib-makeOverridable">
|
||||
<title>lib.makeOverridable</title>
|
||||
|
||||
<para>
|
||||
The function <varname>lib.makeOverridable</varname> is used to make the
|
||||
result of a function easily customizable. This utility only makes sense for
|
||||
functions that accept an argument set and return an attribute set.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example usage:
|
||||
<programlisting>
|
||||
f = { a, b }: { result = a+b; };
|
||||
c = lib.makeOverridable f { a = 1; b = 2; };
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The variable <varname>c</varname> is the value of the <varname>f</varname>
|
||||
function applied with some default arguments. Hence the value of
|
||||
<varname>c.result</varname> is <literal>3</literal>, in this example.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The variable <varname>c</varname> however also has some additional
|
||||
functions, like <link linkend="sec-pkg-override">c.override</link> which can
|
||||
be used to override the default arguments. In this example the value of
|
||||
<varname>(c.override { a = 4; }).result</varname> is 6.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
26
doc/functions/shell.xml
Normal file
26
doc/functions/shell.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="sec-pkgs-mkShell">
|
||||
<title>pkgs.mkShell</title>
|
||||
|
||||
<para>
|
||||
<function>pkgs.mkShell</function> is a special kind of derivation that is
|
||||
only useful when using it combined with <command>nix-shell</command>. It will
|
||||
in fact fail to instantiate when invoked with <command>nix-build</command>.
|
||||
</para>
|
||||
|
||||
<section xml:id="sec-pkgs-mkShell-usage">
|
||||
<title>Usage</title>
|
||||
|
||||
<programlisting><![CDATA[
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
# this will make all the build inputs from hello and gnutar
|
||||
# available to the shell environment
|
||||
inputsFrom = with pkgs; [ hello gnutar ];
|
||||
buildInputs = [ pkgs.gnumake ];
|
||||
}
|
||||
]]></programlisting>
|
||||
</section>
|
||||
</section>
|
@ -11,10 +11,9 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Some libraries require OCaml and sometimes also Camlp5 or findlib. The exact
|
||||
versions that were used to build Coq are saved in the
|
||||
<literal>coq.ocaml</literal> and <literal>coq.camlp5</literal> and
|
||||
<literal>coq.findlib</literal> attributes.
|
||||
Some extensions (plugins) might require OCaml and sometimes other OCaml
|
||||
packages. The <literal>coq.ocamlPackages</literal> attribute can be used to
|
||||
depend on the same package set Coq was built against.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -935,7 +935,7 @@ The implementation can be found in the
|
||||
[integer-gmp](http://hackage.haskell.org/package/integer-gmp) package.
|
||||
|
||||
A potential problem with this is that GMP is licensed under the
|
||||
[GNU Lesser General Public License (LGPL)](http://www.gnu.org/copyleft/lesser.html),
|
||||
[GNU Lesser General Public License (LGPL)](https://www.gnu.org/copyleft/lesser.html),
|
||||
a kind of "copyleft" license. According to the terms of the LGPL, paragraph 5,
|
||||
you may distribute a program that is designed to be compiled and dynamically
|
||||
linked with the library under the terms of your choice (i.e., commercially) but
|
||||
|
@ -1,39 +1,115 @@
|
||||
Idris packages
|
||||
==============
|
||||
# Idris packages
|
||||
|
||||
This directory contains build rules for idris packages. In addition,
|
||||
it contains several functions to build and compose those packages.
|
||||
Everything is exposed to the user via the `idrisPackages` attribute.
|
||||
## Installing Idris
|
||||
|
||||
callPackage
|
||||
------------
|
||||
The easiest way to get a working idris version is to install the `idris` attribute:
|
||||
|
||||
This is like the normal nixpkgs callPackage function, specialized to
|
||||
idris packages.
|
||||
```
|
||||
$ # On NixOS
|
||||
$ nix-env -i nixos.idris
|
||||
$ # On non-NixOS
|
||||
$ nix-env -i nixpkgs.idris
|
||||
```
|
||||
|
||||
builtins
|
||||
---------
|
||||
This however only provides the `prelude` and `base` libraries. To install additional libraries:
|
||||
|
||||
This is a list of all of the libraries that come packaged with Idris
|
||||
itself.
|
||||
```
|
||||
$ nix-env -iE 'pkgs: pkgs.idrisPackages.with-packages (with pkgs.idrisPackages; [ contrib pruviloj ])'
|
||||
```
|
||||
|
||||
build-idris-package
|
||||
--------------------
|
||||
To see all available Idris packages:
|
||||
```
|
||||
$ # On NixOS
|
||||
$ nix-env -qaPA nixos.idrisPackages
|
||||
$ # On non-NixOS
|
||||
$ nix-env -qaPA nixpkgs.idrisPackages
|
||||
```
|
||||
|
||||
A function to build an idris package. Its sole argument is a set like
|
||||
you might pass to `stdenv.mkDerivation`, except `build-idris-package`
|
||||
sets several attributes for you. See `build-idris-package.nix` for
|
||||
details.
|
||||
Similarly, entering a `nix-shell`:
|
||||
```
|
||||
$ nix-shell -p 'idrisPackages.with-packages (with idrisPackages; [ contrib pruviloj ])'
|
||||
```
|
||||
|
||||
build-builtin-package
|
||||
----------------------
|
||||
## Starting Idris with library support
|
||||
|
||||
A version of `build-idris-package` specialized to builtin libraries.
|
||||
Mostly for internal use.
|
||||
To have access to these libraries in idris, call it with an argument `-p <library name>` for each library:
|
||||
|
||||
with-packages
|
||||
-------------
|
||||
```
|
||||
$ nix-shell -p 'idrisPackages.with-packages (with idrisPackages; [ contrib pruviloj ])'
|
||||
[nix-shell:~]$ idris -p contrib -p pruviloj
|
||||
```
|
||||
|
||||
Bundle idris together with a list of packages. Because idris currently
|
||||
only supports a single directory in its library path, you must include
|
||||
all desired libraries here, including `prelude` and `base`.
|
||||
A listing of all available packages the Idris binary has access to is available via `--listlibs`:
|
||||
|
||||
```
|
||||
$ idris --listlibs
|
||||
00prelude-idx.ibc
|
||||
pruviloj
|
||||
base
|
||||
contrib
|
||||
prelude
|
||||
00pruviloj-idx.ibc
|
||||
00base-idx.ibc
|
||||
00contrib-idx.ibc
|
||||
```
|
||||
|
||||
## Building an Idris project with Nix
|
||||
|
||||
As an example of how a Nix expression for an Idris package can be created, here is the one for `idrisPackages.yaml`:
|
||||
|
||||
```nix
|
||||
{ build-idris-package
|
||||
, fetchFromGitHub
|
||||
, contrib
|
||||
, lightyear
|
||||
, lib
|
||||
}:
|
||||
build-idris-package {
|
||||
name = "yaml";
|
||||
version = "2018-01-25";
|
||||
|
||||
# This is the .ipkg file that should be built, defaults to the package name
|
||||
# In this case it should build `Yaml.ipkg` instead of `yaml.ipkg`
|
||||
# This is only necessary because the yaml packages ipkg file is
|
||||
# different from its package name here.
|
||||
ipkgName = "Yaml";
|
||||
# Idris dependencies to provide for the build
|
||||
idrisDeps = [ contrib lightyear ];
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "Heather";
|
||||
repo = "Idris.Yaml";
|
||||
rev = "5afa51ffc839844862b8316faba3bafa15656db4";
|
||||
sha256 = "1g4pi0swmg214kndj85hj50ccmckni7piprsxfdzdfhg87s0avw7";
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "Idris YAML lib";
|
||||
homepage = https://github.com/Heather/Idris.Yaml;
|
||||
license = lib.licenses.mit;
|
||||
maintainers = [ lib.maintainers.brainrape ];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Assuming this file is saved as `yaml.nix`, it's buildable using
|
||||
|
||||
```
|
||||
$ nix-build -E '(import <nixpkgs> {}).idrisPackages.callPackage ./yaml.nix {}'
|
||||
```
|
||||
|
||||
Or it's possible to use
|
||||
|
||||
```nix
|
||||
with import <nixpkgs> {};
|
||||
|
||||
{
|
||||
yaml = idrisPackages.callPackage ./yaml.nix {};
|
||||
}
|
||||
```
|
||||
|
||||
in another file (say `default.nix`) to be able to build it with
|
||||
|
||||
```
|
||||
$ nix-build -A yaml
|
||||
```
|
||||
|
@ -19,6 +19,7 @@
|
||||
<xi:include href="java.xml" />
|
||||
<xi:include href="lua.xml" />
|
||||
<xi:include href="node.section.xml" />
|
||||
<xi:include href="ocaml.xml" />
|
||||
<xi:include href="perl.xml" />
|
||||
<xi:include href="python.section.xml" />
|
||||
<xi:include href="qt.xml" />
|
||||
|
@ -14,7 +14,7 @@ project.
|
||||
|
||||
The package set also provides support for multiple Node.js versions. The policy
|
||||
is that a new package should be added to the collection for the latest stable LTS
|
||||
release (which is currently 8.x), unless there is an explicit reason to support
|
||||
release (which is currently 10.x), unless there is an explicit reason to support
|
||||
a different release.
|
||||
|
||||
If your package uses native addons, you need to examine what kind of native
|
||||
@ -26,7 +26,7 @@ build system it uses. Here are some examples:
|
||||
|
||||
After you have identified the correct system, you need to override your package
|
||||
expression while adding in build system as a build input. For example, `dat`
|
||||
requires `node-gyp-build`, so we override its expression in `default-v8.nix`:
|
||||
requires `node-gyp-build`, so we override its expression in `default-v10.nix`:
|
||||
|
||||
```nix
|
||||
dat = nodePackages.dat.override (oldAttrs: {
|
||||
@ -36,9 +36,9 @@ dat = nodePackages.dat.override (oldAttrs: {
|
||||
|
||||
To add a package from NPM to nixpkgs:
|
||||
|
||||
1. Modify `pkgs/development/node-packages/node-packages-v8.json` to add, update
|
||||
or remove package entries. (Or `pkgs/development/node-packages/node-packages-v10.json`
|
||||
for packages depending on Node.js 10.x)
|
||||
1. Modify `pkgs/development/node-packages/node-packages-v10.json` to add, update
|
||||
or remove package entries. (Or `pkgs/development/node-packages/node-packages-v8.json`
|
||||
for packages depending on Node.js 8.x)
|
||||
2. Run the script: `(cd pkgs/development/node-packages && ./generate.sh)`.
|
||||
3. Build your new package to test your changes:
|
||||
`cd /path/to/nixpkgs && nix-build -A nodePackages.<new-or-updated-package>`.
|
||||
|
99
doc/languages-frameworks/ocaml.xml
Normal file
99
doc/languages-frameworks/ocaml.xml
Normal file
@ -0,0 +1,99 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:id="sec-language-ocaml">
|
||||
<title>OCaml</title>
|
||||
|
||||
<para>
|
||||
OCaml libraries should be installed in
|
||||
<literal>$(out)/lib/ocaml/${ocaml.version}/site-lib/</literal>. Such
|
||||
directories are automatically added to the <literal>$OCAMLPATH</literal>
|
||||
environment variable when building another package that depends on them
|
||||
or when opening a <literal>nix-shell</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Given that most of the OCaml ecosystem is now built with dune,
|
||||
nixpkgs includes a convenience build support function called
|
||||
<literal>buildDunePackage</literal> that will build an OCaml package
|
||||
using dune, OCaml and findlib and any additional dependencies provided
|
||||
as <literal>buildInputs</literal> or <literal>propagatedBuildInputs</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Here is a simple package example. It defines an (optional) attribute
|
||||
<literal>minimumOCamlVersion</literal> that will be used to throw a
|
||||
descriptive evaluation error if building with an older OCaml is attempted.
|
||||
It uses the <literal>fetchFromGitHub</literal> fetcher to get its source.
|
||||
It sets the <literal>doCheck</literal> (optional) attribute to
|
||||
<literal>true</literal> which means that tests will be run with
|
||||
<literal>dune runtest -p angstrom</literal> after the build
|
||||
(<literal>dune build -p angstrom</literal>) is complete.
|
||||
It uses <literal>alcotest</literal> as a build input (because it is needed
|
||||
to run the tests) and <literal>bigstringaf</literal> and
|
||||
<literal>result</literal> as propagated build inputs (thus they will also
|
||||
be available to libraries depending on this library).
|
||||
The library will be installed using the <literal>angstrom.install</literal>
|
||||
file that dune generates.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
{ stdenv, fetchFromGitHub, buildDunePackage, alcotest, result, bigstringaf }:
|
||||
|
||||
buildDunePackage rec {
|
||||
pname = "angstrom";
|
||||
version = "0.10.0";
|
||||
|
||||
minimumOCamlVersion = "4.03";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "inhabitedtype";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
sha256 = "0lh6024yf9ds0nh9i93r9m6p5psi8nvrqxl5x7jwl13zb0r9xfpw";
|
||||
};
|
||||
|
||||
buildInputs = [ alcotest ];
|
||||
propagatedBuildInputs = [ bigstringaf result ];
|
||||
doCheck = true;
|
||||
|
||||
meta = {
|
||||
homepage = https://github.com/inhabitedtype/angstrom;
|
||||
description = "OCaml parser combinators built for speed and memory efficiency";
|
||||
license = stdenv.lib.licenses.bsd3;
|
||||
maintainers = with stdenv.lib.maintainers; [ sternenseemann ];
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Here is a second example, this time using a source archive generated with
|
||||
<literal>dune-release</literal>. It is a good idea to use this archive when
|
||||
it is available as it will usually contain substituted variables such as a
|
||||
<literal>%%VERSION%%</literal> field. This library does not depend
|
||||
on any other OCaml library and no tests are run after building it.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
{ stdenv, fetchurl, buildDunePackage }:
|
||||
|
||||
buildDunePackage rec {
|
||||
pname = "wtf8";
|
||||
version = "1.0.1";
|
||||
|
||||
minimumOCamlVersion = "4.01";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/flowtype/ocaml-${pname}/releases/download/v${version}/${pname}-${version}.tbz";
|
||||
sha256 = "1msg3vycd3k8qqj61sc23qks541cxpb97vrnrvrhjnqxsqnh6ygq";
|
||||
};
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
homepage = https://github.com/flowtype/ocaml-wtf8;
|
||||
description = "WTF-8 is a superset of UTF-8 that allows unpaired surrogates.";
|
||||
license = licenses.mit;
|
||||
maintainers = [ maintainers.eqyiel ];
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
</section>
|
@ -186,7 +186,7 @@ building Python libraries is `buildPythonPackage`. Let's see how we can build th
|
||||
`toolz` package.
|
||||
|
||||
```nix
|
||||
{ # ...
|
||||
{ lib, buildPythonPackage, fetchPypi }:
|
||||
|
||||
toolz = buildPythonPackage rec {
|
||||
pname = "toolz";
|
||||
@ -199,8 +199,8 @@ building Python libraries is `buildPythonPackage`. Let's see how we can build th
|
||||
|
||||
doCheck = false;
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/pytoolz/toolz/";
|
||||
meta = with lib; {
|
||||
homepage = https://github.com/pytoolz/toolz;
|
||||
description = "List processing tools and functional utilities";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ fridh ];
|
||||
@ -267,12 +267,13 @@ that we introduced with the `let` expression.
|
||||
|
||||
#### Handling dependencies
|
||||
|
||||
Our example, `toolz`, does not have any dependencies on other Python
|
||||
packages or system libraries. According to the manual, `buildPythonPackage`
|
||||
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
|
||||
`buildInput`, but if it is (also) a runtime dependency, then it should be added
|
||||
to `propagatedBuildInputs`. Test dependencies are considered build-time dependencies.
|
||||
Our example, `toolz`, does not have any dependencies on other Python packages or
|
||||
system libraries. According to the manual, `buildPythonPackage` 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 `buildInput`, but if it is (also) a runtime dependency, then it
|
||||
should be added to `propagatedBuildInputs`. Test dependencies are considered
|
||||
build-time dependencies and passed to `checkInputs`.
|
||||
|
||||
The following example shows which arguments are given to `buildPythonPackage` in
|
||||
order to build [`datashape`](https://github.com/blaze/datashape).
|
||||
@ -292,7 +293,7 @@ order to build [`datashape`](https://github.com/blaze/datashape).
|
||||
checkInputs = with self; [ pytest ];
|
||||
propagatedBuildInputs = with self; [ numpy multipledispatch dateutil ];
|
||||
|
||||
meta = {
|
||||
meta = with lib; {
|
||||
homepage = https://github.com/ContinuumIO/datashape;
|
||||
description = "A data description language";
|
||||
license = licenses.bsd2;
|
||||
@ -326,7 +327,7 @@ when building the bindings and are therefore added as `buildInputs`.
|
||||
|
||||
buildInputs = with self; [ pkgs.libxml2 pkgs.libxslt ];
|
||||
|
||||
meta = {
|
||||
meta = with lib; {
|
||||
description = "Pythonic binding for the libxml2 and libxslt libraries";
|
||||
homepage = https://lxml.de;
|
||||
license = licenses.bsd3;
|
||||
@ -370,9 +371,9 @@ and `CFLAGS`.
|
||||
export CFLAGS="-I${pkgs.fftw.dev}/include -I${pkgs.fftwFloat.dev}/include -I${pkgs.fftwLongDouble.dev}/include"
|
||||
'';
|
||||
|
||||
meta = {
|
||||
meta = with lib; {
|
||||
description = "A pythonic wrapper around FFTW, the FFT library, presenting a unified interface for all the supported transforms";
|
||||
homepage = http://hgomersall.github.com/pyFFTW/;
|
||||
homepage = http://hgomersall.github.com/pyFFTW;
|
||||
license = with licenses; [ bsd2 bsd3 ];
|
||||
maintainers = with maintainers; [ fridh ];
|
||||
};
|
||||
@ -478,18 +479,16 @@ don't explicitly define which `python` derivation should be used. In the above
|
||||
example we use `buildPythonPackage` that is part of the set `python35Packages`,
|
||||
and in this case the `python35` interpreter is automatically used.
|
||||
|
||||
|
||||
|
||||
## Reference
|
||||
|
||||
### Interpreters
|
||||
|
||||
Versions 2.7, 3.4, 3.5, 3.6 and 3.7 of the CPython interpreter are available as
|
||||
respectively `python27`, `python34`, `python35` and `python36`. The PyPy interpreter
|
||||
is available as `pypy`. The aliases `python2` and `python3` correspond to respectively `python27` and
|
||||
`python35`. The default interpreter, `python`, maps to `python2`.
|
||||
The Nix expressions for the interpreters can be found in
|
||||
`pkgs/development/interpreters/python`.
|
||||
Versions 2.7, 3.5, 3.6 and 3.7 of the CPython interpreter are available as
|
||||
respectively `python27`, `python35`, `python36`, and `python37`. The PyPy
|
||||
interpreter is available as `pypy`. The aliases `python2` and `python3`
|
||||
correspond to respectively `python27` and `python37`. The default interpreter,
|
||||
`python`, maps to `python2`. The Nix expressions for the interpreters can be
|
||||
found in `pkgs/development/interpreters/python`.
|
||||
|
||||
All packages depending on any Python interpreter get appended
|
||||
`out/{python.sitePackages}` to `$PYTHONPATH` if such directory
|
||||
@ -508,7 +507,7 @@ Each interpreter has the following attributes:
|
||||
- `buildEnv`. Function to build python interpreter environments with extra packages bundled together. See section *python.buildEnv function* for usage and documentation.
|
||||
- `withPackages`. Simpler interface to `buildEnv`. See section *python.withPackages function* for usage and documentation.
|
||||
- `sitePackages`. Alias for `lib/${libPrefix}/site-packages`.
|
||||
- `executable`. Name of the interpreter executable, e.g. `python3.4`.
|
||||
- `executable`. Name of the interpreter executable, e.g. `python3.7`.
|
||||
- `pkgs`. Set of Python packages for that specific interpreter. The package set can be modified by overriding the interpreter and passing `packageOverrides`.
|
||||
|
||||
### Building packages and applications
|
||||
@ -530,7 +529,6 @@ attribute set is created for each available Python interpreter. The available
|
||||
sets are
|
||||
|
||||
* `pkgs.python27Packages`
|
||||
* `pkgs.python34Packages`
|
||||
* `pkgs.python35Packages`
|
||||
* `pkgs.python36Packages`
|
||||
* `pkgs.python37Packages`
|
||||
@ -539,7 +537,7 @@ sets are
|
||||
and the aliases
|
||||
|
||||
* `pkgs.python2Packages` pointing to `pkgs.python27Packages`
|
||||
* `pkgs.python3Packages` pointing to `pkgs.python36Packages`
|
||||
* `pkgs.python3Packages` pointing to `pkgs.python37Packages`
|
||||
* `pkgs.pythonPackages` pointing to `pkgs.python2Packages`
|
||||
|
||||
#### `buildPythonPackage` function
|
||||
@ -549,31 +547,31 @@ The `buildPythonPackage` function is implemented in
|
||||
|
||||
The following is an example:
|
||||
```nix
|
||||
{ lib, buildPythonPackage, fetchPypi, hypothesis, setuptools_scm, attrs, py, setuptools, six, pluggy }:
|
||||
|
||||
buildPythonPackage rec {
|
||||
version = "3.3.1";
|
||||
pname = "pytest";
|
||||
|
||||
preCheck = ''
|
||||
# don't test bash builtins
|
||||
rm testing/test_argcomplete.py
|
||||
'';
|
||||
version = "3.3.1";
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "cf8436dc59d8695346fcd3ab296de46425ecab00d64096cebe79fb51ecb2eb93";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
# don't test bash builtins
|
||||
rm testing/test_argcomplete.py
|
||||
'';
|
||||
|
||||
checkInputs = [ hypothesis ];
|
||||
buildInputs = [ setuptools_scm ];
|
||||
propagatedBuildInputs = [ attrs py setuptools six pluggy ];
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
meta = with lib; {
|
||||
maintainers = with maintainers; [ domenkozar lovek323 madjar lsix ];
|
||||
description = "Framework for writing tests";
|
||||
};
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The `buildPythonPackage` mainly does four things:
|
||||
@ -655,6 +653,39 @@ Another difference is that `buildPythonPackage` by default prefixes the names of
|
||||
the packages with the version of the interpreter. Because this is irrelevant for
|
||||
applications, the prefix is omitted.
|
||||
|
||||
When packaging a python application with `buildPythonApplication`, it should be
|
||||
called with `callPackage` and passed `python` or `pythonPackages` (possibly
|
||||
specifying an interpreter version), like this:
|
||||
|
||||
```nix
|
||||
{ lib, python3Packages }:
|
||||
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "luigi";
|
||||
version = "2.7.9";
|
||||
|
||||
src = python3Packages.fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "035w8gqql36zlan0xjrzz9j4lh9hs0qrsgnbyw07qs7lnkvbdv9x";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = with python3Packages; [ tornado_4 python-daemon ];
|
||||
|
||||
meta = with lib; {
|
||||
...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
This is then added to `all-packages.nix` just as any other application would be.
|
||||
|
||||
```nix
|
||||
luigi = callPackage ../applications/networking/cluster/luigi { };
|
||||
```
|
||||
|
||||
Since the package is an application, a consumer doesn't need to care about
|
||||
python versions or modules, which is why they don't go in `pythonPackages`.
|
||||
|
||||
#### `toPythonApplication` function
|
||||
|
||||
A distinction is made between applications and libraries, however, sometimes a
|
||||
@ -805,7 +836,7 @@ community to help save time. No tool is preferred at the moment.
|
||||
|
||||
### Deterministic builds
|
||||
|
||||
Python 2.7, 3.5 and 3.6 are now built deterministically and 3.4 mostly.
|
||||
The Python interpreters are now built deterministically.
|
||||
Minor modifications had to be made to the interpreters in order to generate
|
||||
deterministic bytecode. This has security implications and is relevant for
|
||||
those using Python in a `nix-shell`.
|
||||
@ -1047,8 +1078,7 @@ To modify only a Python package set instead of a whole Python derivation, use th
|
||||
Use the following overlay template:
|
||||
|
||||
```nix
|
||||
self: super:
|
||||
{
|
||||
self: super: {
|
||||
python = super.python.override {
|
||||
packageOverrides = python-self: python-super: {
|
||||
zerobin = python-super.zerobin.overrideAttrs (oldAttrs: {
|
||||
@ -1063,6 +1093,25 @@ self: super:
|
||||
}
|
||||
```
|
||||
|
||||
### How to use Intel's MKL with numpy and scipy?
|
||||
|
||||
A `site.cfg` is created that configures BLAS based on the `blas` parameter
|
||||
of the `numpy` derivation. By passing in `mkl`, `numpy` and packages depending
|
||||
on `numpy` will be built with `mkl`.
|
||||
|
||||
The following is an overlay that configures `numpy` to use `mkl`:
|
||||
```nix
|
||||
self: super: {
|
||||
python36 = super.python36.override {
|
||||
packageOverrides = python-self: python-super: {
|
||||
numpy = python-super.numpy.override {
|
||||
blas = super.pkgs.mkl;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
### Contributing guidelines
|
||||
|
@ -50,6 +50,17 @@ bundlerEnv rec {
|
||||
future updates can be run easily.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Updating Ruby packages can then be done like this:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
<![CDATA[$ cd pkgs/servers/monitoring/sensu
|
||||
$ nix-shell -p bundler --run 'bundle lock --update'
|
||||
$ nix-shell -p bundix --run 'bundix'
|
||||
]]>
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
For tools written in Ruby - i.e. where the desire is to install a package and
|
||||
then execute e.g. <command>rake</command> at the command line, there is an
|
||||
|
@ -64,9 +64,6 @@ When the `Cargo.lock`, provided by upstream, is not in sync with the
|
||||
added in `cargoPatches` will also be prepended to the patches in `patches` at
|
||||
build-time.
|
||||
|
||||
To install crates with nix there is also an experimental project called
|
||||
[nixcrates](https://github.com/fractalide/nixcrates).
|
||||
|
||||
## Compiling Rust crates using Nix instead of Cargo
|
||||
|
||||
### Simple operation
|
||||
|
@ -49,12 +49,12 @@ texlive.combine {
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You can list packages e.g. by <command>nix-repl</command>.
|
||||
<programlisting>
|
||||
$ nix-repl
|
||||
nix-repl> :l <nixpkgs>
|
||||
nix-repl> texlive.collection-<TAB>
|
||||
</programlisting>
|
||||
You can list packages e.g. by <command>nix repl</command>.
|
||||
<programlisting><![CDATA[
|
||||
$ nix repl
|
||||
nix-repl> :l <nixpkgs>
|
||||
nix-repl> texlive.collection-<TAB>
|
||||
]]></programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
@ -5,11 +5,17 @@ date: 2016-06-25
|
||||
---
|
||||
# User's Guide to Vim Plugins/Addons/Bundles/Scripts in Nixpkgs
|
||||
|
||||
You'll get a vim(-your-suffix) in PATH also loading the plugins you want.
|
||||
Both Neovim and Vim can be configured to include your favorite plugins
|
||||
and additional libraries.
|
||||
|
||||
Loading can be deferred; see examples.
|
||||
|
||||
Vim packages, VAM (=vim-addon-manager) and Pathogen are supported to load
|
||||
packages.
|
||||
At the moment we support three different methods for managing plugins:
|
||||
|
||||
- Vim packages (*recommend*)
|
||||
- VAM (=vim-addon-manager)
|
||||
- Pathogen
|
||||
- vim-plug
|
||||
|
||||
## Custom configuration
|
||||
|
||||
@ -17,6 +23,7 @@ Adding custom .vimrc lines can be done using the following code:
|
||||
|
||||
```
|
||||
vim_configurable.customize {
|
||||
# `name` specifies the name of the executable and package
|
||||
name = "vim-with-plugins";
|
||||
|
||||
vimrcConfig.customRC = ''
|
||||
@ -25,7 +32,21 @@ vim_configurable.customize {
|
||||
}
|
||||
```
|
||||
|
||||
## Vim packages
|
||||
This configuration is used when vim is invoked with the command specified as name, in this case `vim-with-plugins`.
|
||||
|
||||
For Neovim the `configure` argument can be overridden to achieve the same:
|
||||
|
||||
```
|
||||
neovim.override {
|
||||
configure = {
|
||||
customRC = ''
|
||||
# here your custom configuration goes!
|
||||
'';
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Managing plugins with Vim packages
|
||||
|
||||
To store you plugins in Vim packages the following example can be used:
|
||||
|
||||
@ -38,13 +59,80 @@ vim_configurable.customize {
|
||||
opt = [ phpCompletion elm-vim ];
|
||||
# To automatically load a plugin when opening a filetype, add vimrc lines like:
|
||||
# autocmd FileType php :packadd phpCompletion
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## VAM
|
||||
For Neovim the syntax is:
|
||||
|
||||
### dependencies by Vim plugins
|
||||
```
|
||||
neovim.override {
|
||||
configure = {
|
||||
customRC = ''
|
||||
# here your custom configuration goes!
|
||||
'';
|
||||
packages.myVimPackage = with pkgs.vimPlugins; {
|
||||
# see examples below how to use custom packages
|
||||
start = [ ];
|
||||
opt = [ ];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
The resulting package can be added to `packageOverrides` in `~/.nixpkgs/config.nix` to make it installable:
|
||||
|
||||
```
|
||||
{
|
||||
packageOverrides = pkgs: with pkgs; {
|
||||
myVim = vim_configurable.customize {
|
||||
# `name` specifies the name of the executable and package
|
||||
name = "vim-with-plugins";
|
||||
# add here code from the example section
|
||||
};
|
||||
myNeovim = neovim.override {
|
||||
configure = {
|
||||
# add here code from the example section
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
After that you can install your special grafted `myVim` or `myNeovim` packages.
|
||||
|
||||
## Managing plugins with vim-plug
|
||||
|
||||
To use [vim-plug](https://github.com/junegunn/vim-plug) to manage your Vim
|
||||
plugins the following example can be used:
|
||||
|
||||
```
|
||||
vim_configurable.customize {
|
||||
vimrcConfig.packages.myVimPackage = with pkgs.vimPlugins; {
|
||||
# loaded on launch
|
||||
plug.plugins = [ youcompleteme fugitive phpCompletion elm-vim ];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
For Neovim the syntax is:
|
||||
|
||||
```
|
||||
neovim.override {
|
||||
configure = {
|
||||
customRC = ''
|
||||
# here your custom configuration goes!
|
||||
'';
|
||||
plug.plugins = with pkgs.vimPlugins; [
|
||||
vim-go
|
||||
];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Managing plugins with VAM
|
||||
|
||||
### Handling dependencies of Vim plugins
|
||||
|
||||
VAM introduced .json files supporting dependencies without versioning
|
||||
assuming that "using latest version" is ok most of the time.
|
||||
@ -125,6 +213,18 @@ Sample output2:
|
||||
]
|
||||
|
||||
|
||||
## Adding new plugins to nixpkgs
|
||||
|
||||
In `pkgs/misc/vim-plugins/vim-plugin-names` we store the plugin names
|
||||
for all vim plugins we automatically generate plugins for.
|
||||
The format of this file `github username/github repository`:
|
||||
For example https://github.com/scrooloose/nerdtree becomes `scrooloose/nerdtree`.
|
||||
After adding your plugin to this file run the `./update.py` in the same folder.
|
||||
This will updated a file called `generated.nix` and make your plugin accessible in the
|
||||
`vimPlugins` attribute set (`vimPlugins.nerdtree` in our example).
|
||||
If additional steps to the build process of the plugin are required, add an
|
||||
override to the `pkgs/misc/vim-plugins/default.nix` in the same directory.
|
||||
|
||||
## Important repositories
|
||||
|
||||
- [vim-pi](https://bitbucket.org/vimcommunity/vim-pi) is a plugin repository
|
||||
|
85
doc/lib-function-locations.nix
Normal file
85
doc/lib-function-locations.nix
Normal file
@ -0,0 +1,85 @@
|
||||
{ pkgs ? (import ./.. { }), nixpkgs ? { }}:
|
||||
let
|
||||
revision = pkgs.lib.trivial.revisionWithDefault (nixpkgs.revision or "master");
|
||||
|
||||
libDefPos = set:
|
||||
builtins.map
|
||||
(name: {
|
||||
name = name;
|
||||
location = builtins.unsafeGetAttrPos name set;
|
||||
})
|
||||
(builtins.attrNames set);
|
||||
|
||||
libset = toplib:
|
||||
builtins.map
|
||||
(subsetname: {
|
||||
subsetname = subsetname;
|
||||
functions = libDefPos toplib."${subsetname}";
|
||||
})
|
||||
(builtins.filter
|
||||
(name: builtins.isAttrs toplib."${name}")
|
||||
(builtins.attrNames toplib));
|
||||
|
||||
nixpkgsLib = pkgs.lib;
|
||||
|
||||
flattenedLibSubset = { subsetname, functions }:
|
||||
builtins.map
|
||||
(fn: {
|
||||
name = "lib.${subsetname}.${fn.name}";
|
||||
value = fn.location;
|
||||
})
|
||||
functions;
|
||||
|
||||
locatedlibsets = libs: builtins.map flattenedLibSubset (libset libs);
|
||||
removeFilenamePrefix = prefix: filename:
|
||||
let
|
||||
prefixLen = (builtins.stringLength prefix) + 1; # +1 to remove the leading /
|
||||
filenameLen = builtins.stringLength filename;
|
||||
substr = builtins.substring prefixLen filenameLen filename;
|
||||
in substr;
|
||||
|
||||
removeNixpkgs = removeFilenamePrefix (builtins.toString pkgs.path);
|
||||
|
||||
liblocations =
|
||||
builtins.filter
|
||||
(elem: elem.value != null)
|
||||
(nixpkgsLib.lists.flatten
|
||||
(locatedlibsets nixpkgsLib));
|
||||
|
||||
fnLocationRelative = { name, value }:
|
||||
{
|
||||
inherit name;
|
||||
value = value // { file = removeNixpkgs value.file; };
|
||||
};
|
||||
|
||||
relativeLocs = (builtins.map fnLocationRelative liblocations);
|
||||
sanitizeId = builtins.replaceStrings
|
||||
[ "'" ]
|
||||
[ "-prime" ];
|
||||
|
||||
urlPrefix = "https://github.com/NixOS/nixpkgs/blob/${revision}";
|
||||
xmlstrings = (nixpkgsLib.strings.concatMapStrings
|
||||
({ name, value }:
|
||||
''
|
||||
<section><title>${name}</title>
|
||||
<para xml:id="${sanitizeId name}">
|
||||
Located at
|
||||
<link
|
||||
xlink:href="${urlPrefix}/${value.file}#L${builtins.toString value.line}">${value.file}:${builtins.toString value.line}</link>
|
||||
in <literal><nixpkgs></literal>.
|
||||
</para>
|
||||
</section>
|
||||
'')
|
||||
relativeLocs);
|
||||
|
||||
in pkgs.writeText
|
||||
"locations.xml"
|
||||
''
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="5">
|
||||
<title>All the locations for every lib function</title>
|
||||
<para>This file is only for inclusion by other files.</para>
|
||||
${xmlstrings}
|
||||
</section>
|
||||
''
|
62
doc/meta.xml
62
doc/meta.xml
@ -14,7 +14,7 @@ meta = with stdenv.lib; {
|
||||
GNU Hello is a program that prints "Hello, world!" when you run it.
|
||||
It is fully customizable.
|
||||
'';
|
||||
homepage = http://www.gnu.org/software/hello/manual/;
|
||||
homepage = https://www.gnu.org/software/hello/manual/;
|
||||
license = licenses.gpl3Plus;
|
||||
maintainers = [ maintainers.eelco ];
|
||||
platforms = platforms.all;
|
||||
@ -35,7 +35,7 @@ $ nix-env -qa hello --json
|
||||
"hello": {
|
||||
"meta": {
|
||||
"description": "A program that produces a familiar, friendly greeting",
|
||||
"homepage": "http://www.gnu.org/software/hello/manual/",
|
||||
"homepage": "https://www.gnu.org/software/hello/manual/",
|
||||
"license": {
|
||||
"fullName": "GNU General Public License version 3 or later",
|
||||
"shortName": "GPLv3+",
|
||||
@ -135,7 +135,7 @@ hello-2.3 A program that produces a familiar, friendly greeting
|
||||
<listitem>
|
||||
<para>
|
||||
The package’s homepage. Example:
|
||||
<literal>http://www.gnu.org/software/hello/manual/</literal>
|
||||
<literal>https://www.gnu.org/software/hello/manual/</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -146,7 +146,7 @@ hello-2.3 A program that produces a familiar, friendly greeting
|
||||
<listitem>
|
||||
<para>
|
||||
The page where a link to the current version can be found. Example:
|
||||
<literal>http://ftp.gnu.org/gnu/hello/</literal>
|
||||
<literal>https://ftp.gnu.org/gnu/hello/</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -250,6 +250,60 @@ meta.platforms = stdenv.lib.platforms.linux;
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>tests</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<warning>
|
||||
<para>
|
||||
This attribute is special in that it is not actually under the
|
||||
<literal>meta</literal> attribute set but rather under the
|
||||
<literal>passthru</literal> attribute set. This is due to a current
|
||||
limitation of Nix, and will change as soon as Nixpkgs will be able to
|
||||
depend on a new enough version of Nix. See
|
||||
<link xlink:href="https://github.com/NixOS/nix/issues/2532">the relevant
|
||||
issue</link> for more details.
|
||||
</para>
|
||||
</warning>
|
||||
<para>
|
||||
An attribute set with as values tests. A test is a derivation, which
|
||||
builds successfully when the test passes, and fails to build otherwise. A
|
||||
derivation that is a test needs to have <literal>meta.timeout</literal>
|
||||
defined.
|
||||
</para>
|
||||
<para>
|
||||
The NixOS tests are available as <literal>nixosTests</literal> in
|
||||
parameters of derivations. For instance, the OpenSMTPD derivation
|
||||
includes lines similar to:
|
||||
<programlisting>
|
||||
{ /* ... */, nixosTests }:
|
||||
{
|
||||
# ...
|
||||
passthru.tests = {
|
||||
basic-functionality-and-dovecot-integration = nixosTests.opensmtpd;
|
||||
};
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>timeout</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A timeout (in seconds) for building the derivation. If the derivation
|
||||
takes longer than this time to build, it can fail due to breaking the
|
||||
timeout. However, all computers do not have the same computing power,
|
||||
hence some builders may decide to apply a multiplicative factor to this
|
||||
value. When filling this value in, try to keep it approximately
|
||||
consistent with other values already present in
|
||||
<literal>nixpkgs</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>hydraPlatforms</varname>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<para>
|
||||
The Nix language allows a derivation to produce multiple outputs, which is
|
||||
similar to what is utilized by other Linux distribution packaging systems.
|
||||
The outputs reside in separate nix store paths, so they can be mostly
|
||||
The outputs reside in separate Nix store paths, so they can be mostly
|
||||
handled independently of each other, including passing to build inputs,
|
||||
garbage collection or binary substitution. The exception is that building
|
||||
from source always produces all the outputs.
|
||||
|
197
doc/overlays.xml
197
doc/overlays.xml
@ -3,9 +3,9 @@
|
||||
xml:id="chap-overlays">
|
||||
<title>Overlays</title>
|
||||
<para>
|
||||
This chapter describes how to extend and change Nixpkgs packages using
|
||||
overlays. Overlays are used to add layers in the fix-point used by Nixpkgs to
|
||||
compose the set of all packages.
|
||||
This chapter describes how to extend and change Nixpkgs using overlays.
|
||||
Overlays are used to add layers in the fixed-point used by Nixpkgs to compose
|
||||
the set of all packages.
|
||||
</para>
|
||||
<para>
|
||||
Nixpkgs can be configured with a list of overlays, which are applied in
|
||||
@ -17,91 +17,122 @@
|
||||
<title>Installing overlays</title>
|
||||
|
||||
<para>
|
||||
The list of overlays is determined as follows.
|
||||
The list of overlays can be set either explicitly in a Nix expression, or
|
||||
through <literal><nixpkgs-overlays></literal> or user configuration
|
||||
files.
|
||||
</para>
|
||||
|
||||
<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>
|
||||
<listitem>
|
||||
<para>
|
||||
First, if an <varname>overlays</varname> argument to the nixpkgs function
|
||||
itself is given, then that is used.
|
||||
</para>
|
||||
<para>
|
||||
This can be passed explicitly when importing nipxkgs, for example
|
||||
<literal>import <nixpkgs> { overlays = [ overlay1 overlay2 ];
|
||||
}</literal>.
|
||||
</para>
|
||||
</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>
|
||||
See the section on <literal>NIX_PATH</literal> in the Nix manual for more
|
||||
details on how to set a value for
|
||||
<literal><nixpkgs-overlays>.</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If one of <filename>~/.config/nixpkgs/overlays.nix</filename> and
|
||||
<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>
|
||||
</orderedlist>
|
||||
</para>
|
||||
<section xml:id="sec-overlays-argument">
|
||||
<title>Set overlays in NixOS or Nix expressions</title>
|
||||
|
||||
<para>
|
||||
If we are looking for overlays at a path, then there are two cases:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<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>
|
||||
<listitem>
|
||||
<para>
|
||||
If the path is a directory, then we take the content of the directory,
|
||||
order it 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>
|
||||
On a NixOS system the value of the <literal>nixpkgs.overlays</literal>
|
||||
option, if present, 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
|
||||
<link xlink:href="#sec-overlays-lookup">looked</link> up independently.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On a NixOS system the value of the <literal>nixpkgs.overlays</literal>
|
||||
option, if present, 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 list of overlays can be passed explicitly when importing nixpkgs, for
|
||||
example <literal>import <nixpkgs> { overlays = [ overlay1 overlay2 ];
|
||||
}</literal>.
|
||||
</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>
|
||||
<para>
|
||||
Further overlays can be added by calling the <literal>pkgs.extend</literal>
|
||||
or <literal>pkgs.appendOverlays</literal>, although it is often preferable
|
||||
to avoid these functions, because they recompute the Nixpkgs fixpoint,
|
||||
which is somewhat expensive to do.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-overlays-lookup">
|
||||
<title>Install overlays via configuration lookup</title>
|
||||
|
||||
<para>
|
||||
The list of overlays is determined as follows.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
First, if an
|
||||
<link xlink:href="#sec-overlays-argument"><varname>overlays</varname>
|
||||
argument</link> to the Nixpkgs function itself is given, then that is
|
||||
used and no path lookup will be performed.
|
||||
</para>
|
||||
</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>
|
||||
See the section on <literal>NIX_PATH</literal> in the Nix manual for
|
||||
more details on how to set a value for
|
||||
<literal><nixpkgs-overlays>.</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If one of <filename>~/.config/nixpkgs/overlays.nix</filename> and
|
||||
<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>
|
||||
</orderedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If we are looking for overlays at a path, then there are two cases:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<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>
|
||||
<listitem>
|
||||
<para>
|
||||
If the path is a directory, then we take the content of the directory,
|
||||
order it 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>
|
||||
Because overlays that are set in NixOS configuration do not affect
|
||||
non-NixOS operations such as <literal>nix-env</literal>, the
|
||||
<filename>overlays.nix</filename> option 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>
|
||||
|
||||
<!-- TODO: Example of sharing overlays between NixOS configuration
|
||||
and configuration lookup. Also reference the example
|
||||
from the sec-overlays-argument paragraph about NixOS.
|
||||
-->
|
||||
</section>
|
||||
</section>
|
||||
<!--============================================================-->
|
||||
<section xml:id="sec-overlays-definition">
|
||||
|
@ -205,7 +205,7 @@ $ cat $(PRINT_PATH=1 nix-prefetch-url $i | tail -n 1) \
|
||||
|
||||
<para>
|
||||
Nixpkgs provides a number of packages that will install Eclipse in its
|
||||
various forms, these range from the bare-bones Eclipse Platform to the more
|
||||
various forms. These range from the bare-bones Eclipse Platform to the more
|
||||
fully featured Eclipse SDK or Scala-IDE packages and multiple version are
|
||||
often available. It is possible to list available Eclipse packages by
|
||||
issuing the command:
|
||||
@ -413,11 +413,9 @@ packageOverrides = pkgs: {
|
||||
in your <filename>/etc/nixos/configuration.nix</filename>. You'll also need
|
||||
<programlisting>hardware.pulseaudio.support32Bit = true;</programlisting>
|
||||
if you are using PulseAudio - this will enable 32bit ALSA apps integration.
|
||||
To use the Steam controller, you need to add
|
||||
<programlisting>services.udev.extraRules = ''
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="28de", MODE="0666"
|
||||
KERNEL=="uinput", MODE="0660", GROUP="users", OPTIONS+="static_node=uinput"
|
||||
'';</programlisting>
|
||||
To use the Steam controller or other Steam supported controllers such as
|
||||
the DualShock 4 or Nintendo Switch Pro, you need to add
|
||||
<programlisting>hardware.steam-hardware.enable = true;</programlisting>
|
||||
to your configuration.
|
||||
</para>
|
||||
</section>
|
||||
@ -671,6 +669,9 @@ overrides = self: super: rec {
|
||||
plugins = with availablePlugins; [ python perl ];
|
||||
}
|
||||
}</programlisting>
|
||||
If the <literal>configure</literal> function returns an attrset without the
|
||||
<literal>plugins</literal> attribute, <literal>availablePlugins</literal>
|
||||
will be used automatically.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -680,10 +681,10 @@ overrides = self: super: rec {
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The python plugin allows the addition of extra libraries. For instance, the
|
||||
<literal>inotify.py</literal> script in weechat-scripts requires D-Bus or
|
||||
libnotify, and the <literal>fish.py</literal> script requires pycrypto. To
|
||||
use these scripts, use the <literal>python</literal> plugin's
|
||||
The python and perl plugins allows the addition of extra libraries. For
|
||||
instance, the <literal>inotify.py</literal> script in weechat-scripts
|
||||
requires D-Bus or libnotify, and the <literal>fish.py</literal> script
|
||||
requires pycrypto. To use these scripts, use the plugin's
|
||||
<literal>withPackages</literal> attribute:
|
||||
<programlisting>weechat.override { configure = {availablePlugins, ...}: {
|
||||
plugins = with availablePlugins; [
|
||||
@ -704,6 +705,61 @@ overrides = self: super: rec {
|
||||
}; }
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
WeeChat allows to set defaults on startup using the
|
||||
<literal>--run-command</literal>. The <literal>configure</literal> method
|
||||
can be used to pass commands to the program:
|
||||
<programlisting>weechat.override {
|
||||
configure = { availablePlugins, ... }: {
|
||||
init = ''
|
||||
/set foo bar
|
||||
/server add freenode chat.freenode.org
|
||||
'';
|
||||
};
|
||||
}</programlisting>
|
||||
Further values can be added to the list of commands when running
|
||||
<literal>weechat --run-command "your-commands"</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Additionally it's possible to specify scripts to be loaded when starting
|
||||
<literal>weechat</literal>. These will be loaded before the commands from
|
||||
<literal>init</literal>:
|
||||
<programlisting>weechat.override {
|
||||
configure = { availablePlugins, ... }: {
|
||||
scripts = with pkgs.weechatScripts; [
|
||||
weechat-xmpp weechat-matrix-bridge wee-slack
|
||||
];
|
||||
init = ''
|
||||
/set plugins.var.python.jabber.key "val"
|
||||
'':
|
||||
};
|
||||
}</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In <literal>nixpkgs</literal> there's a subpackage which contains
|
||||
derivations for WeeChat scripts. Such derivations expect a
|
||||
<literal>passthru.scripts</literal> attribute which contains a list of all
|
||||
scripts inside the store path. Furthermore all scripts have to live in
|
||||
<literal>$out/share</literal>. An exemplary derivation looks like this:
|
||||
<programlisting>{ stdenv, fetchurl }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "exemplary-weechat-script";
|
||||
src = fetchurl {
|
||||
url = "https://scripts.tld/your-scripts.tar.gz";
|
||||
sha256 = "...";
|
||||
};
|
||||
passthru.scripts = [ "foo.py" "bar.lua" ];
|
||||
installPhase = ''
|
||||
mkdir $out/share
|
||||
cp foo.py $out/share
|
||||
cp bar.lua $out/share
|
||||
'';
|
||||
}</programlisting>
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="sec-citrix">
|
||||
<title>Citrix Receiver</title>
|
||||
@ -763,4 +819,75 @@ citrix_receiver.override {
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="sec-ibus-typing-booster">
|
||||
<title>ibus-engines.typing-booster</title>
|
||||
|
||||
<para>
|
||||
This package is an ibus-based completion method to speed up typing.
|
||||
</para>
|
||||
|
||||
<section xml:id="sec-ibus-typing-booster-activate">
|
||||
<title>Activating the engine</title>
|
||||
|
||||
<para>
|
||||
IBus needs to be configured accordingly to activate
|
||||
<literal>typing-booster</literal>. The configuration depends on the desktop
|
||||
manager in use. For detailed instructions, please refer to the
|
||||
<link xlink:href="https://mike-fabian.github.io/ibus-typing-booster/documentation.html">upstream
|
||||
docs</link>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On NixOS you need to explicitly enable <literal>ibus</literal> with given
|
||||
engines before customizing your desktop to use
|
||||
<literal>typing-booster</literal>. This can be achieved using the
|
||||
<literal>ibus</literal> module:
|
||||
<programlisting>{ pkgs, ... }: {
|
||||
i18n.inputMethod = {
|
||||
enabled = "ibus";
|
||||
ibus.engines = with pkgs.ibus-engines; [ typing-booster ];
|
||||
};
|
||||
}</programlisting>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-ibus-typing-booster-customize-hunspell">
|
||||
<title>Using custom hunspell dictionaries</title>
|
||||
|
||||
<para>
|
||||
The IBus engine is based on <literal>hunspell</literal> to support
|
||||
completion in many languages. By default the dictionaries
|
||||
<literal>de-de</literal>, <literal>en-us</literal>,
|
||||
<literal>es-es</literal>, <literal>it-it</literal>,
|
||||
<literal>sv-se</literal> and <literal>sv-fi</literal> are in use. To add
|
||||
another dictionary, the package can be overridden like this:
|
||||
<programlisting>ibus-engines.typing-booster.override {
|
||||
langs = [ "de-at" "en-gb" ];
|
||||
}</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<emphasis>Note: each language passed to <literal>langs</literal> must be an
|
||||
attribute name in <literal>pkgs.hunspellDicts</literal>.</emphasis>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-ibus-typing-booster-emoji-picker">
|
||||
<title>Built-in emoji picker</title>
|
||||
|
||||
<para>
|
||||
The <literal>ibus-engines.typing-booster</literal> package contains a
|
||||
program named <literal>emoji-picker</literal>. To display all emojis
|
||||
correctly, a special font such as <literal>noto-fonts-emoji</literal> is
|
||||
needed:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On NixOS it can be installed using the following expression:
|
||||
<programlisting>{ pkgs, ... }: {
|
||||
fonts.fonts = with pkgs; [ noto-fonts-emoji ];
|
||||
}</programlisting>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
@ -6,13 +6,13 @@
|
||||
<title>Darwin (macOS)</title>
|
||||
|
||||
<para>
|
||||
Some common issues when packaging software for darwin:
|
||||
Some common issues when packaging software for Darwin:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The darwin <literal>stdenv</literal> uses clang instead of gcc. When
|
||||
The Darwin <literal>stdenv</literal> uses clang instead of gcc. When
|
||||
referring to the compiler <varname>$CC</varname> or <command>cc</command>
|
||||
will work in both cases. Some builds hardcode gcc/g++ in their build
|
||||
scripts, that can usually be fixed with using something like
|
||||
@ -31,7 +31,7 @@
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
On darwin libraries are linked using absolute paths, libraries are
|
||||
On Darwin, libraries are linked using absolute paths, libraries are
|
||||
resolved by their <literal>install_name</literal> at link time. Sometimes
|
||||
packages won't set this correctly causing the library lookups to fail at
|
||||
runtime. This can be fixed by adding extra linker flags or by running
|
||||
@ -96,8 +96,8 @@
|
||||
</programlisting>
|
||||
<para>
|
||||
The package <literal>xcbuild</literal> can be used to build projects that
|
||||
really depend on Xcode, however projects that build some kind of graphical
|
||||
interface won't work without using Xcode in an impure way.
|
||||
really depend on Xcode. However, this replacement is not 100%
|
||||
compatible with Xcode and can occasionally cause issues.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
@ -147,8 +147,8 @@ $ git add pkgs/development/libraries/libfoo/default.nix</screen>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You can use <command>nix-prefetch-url</command> (or similar
|
||||
nix-prefetch-git, etc) <replaceable>url</replaceable> to get the
|
||||
You can use <command>nix-prefetch-url</command>
|
||||
<replaceable>url</replaceable> to get the
|
||||
SHA-256 hash of source distributions. There are similar commands as
|
||||
<command>nix-prefetch-git</command> and
|
||||
<command>nix-prefetch-hg</command> available in
|
||||
|
@ -17,22 +17,20 @@
|
||||
</para>
|
||||
</warning>
|
||||
<para>
|
||||
The nixpkgs project receives a fairly high number of contributions via GitHub
|
||||
pull-requests. Reviewing and approving these is an important task and a way
|
||||
The Nixpkgs project receives a fairly high number of contributions via GitHub
|
||||
pull requests. Reviewing and approving these is an important task and a way
|
||||
to contribute to the project.
|
||||
</para>
|
||||
<para>
|
||||
The high change rate of nixpkgs makes any pull request that remains open for
|
||||
The high change rate of Nixpkgs makes any pull request that remains open for
|
||||
too long subject to conflicts that will require extra work from the 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
|
||||
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
|
||||
recently</link> and the
|
||||
<link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-asc">least
|
||||
recently</link> updated pull-requests. We highly encourage looking at
|
||||
or the merger. Reviewing pull requests in a timely manner and being responsive
|
||||
to the comments is the key to avoid this issue. GitHub provides sort 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
|
||||
recently</link> and the <link
|
||||
xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-asc">least
|
||||
recently</link> updated pull requests. We highly encourage looking at
|
||||
<link xlink:href="https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+review%3Anone+status%3Asuccess+-label%3A%222.status%3A+work-in-progress%22+no%3Aproject+no%3Aassignee+no%3Amilestone">
|
||||
this list of ready to merge, unreviewed pull requests</link>.
|
||||
</para>
|
||||
@ -43,12 +41,12 @@
|
||||
</para>
|
||||
<para>
|
||||
GitHub provides reactions as a simple and quick way to provide feedback to
|
||||
pull-requests or any comments. The thumb-down reaction should be used with
|
||||
pull requests or any comments. The thumb-down reaction should be used with
|
||||
care and if possible accompanied with some explanation so the submitter has
|
||||
directions to improve their contribution.
|
||||
</para>
|
||||
<para>
|
||||
Pull-request reviews should include a list of what has been reviewed in a
|
||||
pull request reviews should include a list of what has been reviewed in a
|
||||
comment, so other reviewers and mergers can know the state of the review.
|
||||
</para>
|
||||
<para>
|
||||
@ -60,8 +58,8 @@
|
||||
<title>Package updates</title>
|
||||
|
||||
<para>
|
||||
A package update is the most trivial and common type of pull-request. These
|
||||
pull-requests mainly consist of updating the version part of the package
|
||||
A package update is the most trivial and common type of pull request. These
|
||||
pull requests mainly consist of updating the version part of the package
|
||||
name and the source hash.
|
||||
</para>
|
||||
|
||||
@ -77,7 +75,7 @@
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Add labels to the pull-request. (Requires commit rights)
|
||||
Add labels to the pull request. (Requires commit rights)
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
@ -144,8 +142,8 @@
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Pull-requests are often targeted to the master or staging branch, and
|
||||
building the pull-request locally when it is submitted can trigger many
|
||||
pull requests are often targeted to the master or staging branch, and
|
||||
building the pull request locally when it is submitted can trigger many
|
||||
source builds.
|
||||
</para>
|
||||
<para>
|
||||
@ -174,14 +172,14 @@ $ git rebase --onto nixos-unstable BASEBRANCH FETCH_HEAD <co
|
||||
</callout>
|
||||
<callout arearefs='reviewing-rebase-3'>
|
||||
<para>
|
||||
Fetching the pull-request changes, <varname>PRNUMBER</varname> is the
|
||||
number at the end of the pull-request title and
|
||||
<varname>BASEBRANCH</varname> the base branch of the pull-request.
|
||||
Fetching the pull request changes, <varname>PRNUMBER</varname> is the
|
||||
number at the end of the pull request title and
|
||||
<varname>BASEBRANCH</varname> the base branch of the pull request.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='reviewing-rebase-4'>
|
||||
<para>
|
||||
Rebasing the pull-request changes to the nixos-unstable branch.
|
||||
Rebasing the pull request changes to the nixos-unstable branch.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
@ -190,10 +188,10 @@ $ git rebase --onto nixos-unstable BASEBRANCH FETCH_HEAD <co
|
||||
<listitem>
|
||||
<para>
|
||||
The <link xlink:href="https://github.com/madjar/nox">nox</link> tool can
|
||||
be used to review a pull-request content in a single command. It doesn't
|
||||
be used to review a pull request content in a single command. It doesn't
|
||||
rebase on a channel branch so it might trigger multiple source builds.
|
||||
<varname>PRNUMBER</varname> should be replaced by the number at the end
|
||||
of the pull-request title.
|
||||
of the pull request title.
|
||||
</para>
|
||||
<screen>
|
||||
$ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
@ -230,7 +228,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
<title>New packages</title>
|
||||
|
||||
<para>
|
||||
New packages are a common type of pull-requests. These pull requests
|
||||
New packages are a common type of pull requests. These pull requests
|
||||
consists in adding a new nix-expression for a package.
|
||||
</para>
|
||||
|
||||
@ -241,7 +239,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Add labels to the pull-request. (Requires commit rights)
|
||||
Add labels to the pull request. (Requires commit rights)
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
@ -279,7 +277,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
A maintainer must be set, this can be the package submitter or a
|
||||
A maintainer must be set. This can be the package submitter or a
|
||||
community member that accepts to take maintainership of the package.
|
||||
</para>
|
||||
</listitem>
|
||||
@ -361,7 +359,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Add labels to the pull-request. (Requires commit rights)
|
||||
Add labels to the pull request. (Requires commit rights)
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
@ -474,7 +472,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Add labels to the pull-request. (Requires commit rights)
|
||||
Add labels to the pull request. (Requires commit rights)
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
@ -576,7 +574,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
like to be a long-term reviewer for related submissions, please contact the
|
||||
current reviewers for that topic. They will give you information about the
|
||||
reviewing process. The main reviewers for a topic can be hard to find as
|
||||
there is no list, but checking past pull-requests to see who reviewed or
|
||||
there is no list, but checking past pull requests to see who reviewed or
|
||||
git-blaming the code to see who committed to that topic can give some hints.
|
||||
</para>
|
||||
|
||||
@ -586,7 +584,7 @@ $ nix-shell -p nox --run "nox-review -k pr PRNUMBER"
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="reviewing-contributions--merging-pull-requests">
|
||||
<title>Merging pull-requests</title>
|
||||
<title>Merging pull requests</title>
|
||||
|
||||
<para>
|
||||
It is possible for community members that have enough knowledge and
|
||||
|
@ -1,5 +1,5 @@
|
||||
{ pkgs ? import ../. {} }:
|
||||
(import ./default.nix).overrideAttrs (x: {
|
||||
(import ./default.nix {}).overrideAttrs (x: {
|
||||
buildInputs = x.buildInputs ++ [ pkgs.xmloscopy pkgs.ruby ];
|
||||
|
||||
})
|
||||
|
@ -1,22 +0,0 @@
|
||||
---
|
||||
title: pkgs.mkShell
|
||||
author: zimbatm
|
||||
date: 2017-10-30
|
||||
---
|
||||
|
||||
# mkShell
|
||||
|
||||
pkgs.mkShell is a special kind of derivation that is only useful when using
|
||||
it combined with nix-shell. It will in fact fail to instantiate when invoked
|
||||
with nix-build.
|
||||
|
||||
## Usage
|
||||
|
||||
```nix
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
# this will make all the build inputs from hello and gnutar available to the shell environment
|
||||
inputsFrom = with pkgs; [ hello gnutar ];
|
||||
buildInputs = [ pkgs.gnumake ];
|
||||
}
|
||||
```
|
651
doc/stdenv.xml
651
doc/stdenv.xml
@ -228,18 +228,19 @@ genericBuild
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The extension of <envar>PATH</envar> with dependencies, alluded to above,
|
||||
proceeds according to the relative platforms alone. The process is carried
|
||||
out only for dependencies whose host platform matches the new derivation's
|
||||
build platform–i.e. which run on the platform where the new derivation
|
||||
will be built.
|
||||
The extension of <envar>PATH</envar> with dependencies, alluded to
|
||||
above, proceeds according to the relative platforms alone. The
|
||||
process is carried out only for dependencies whose host platform
|
||||
matches the new derivation's build platform i.e. dependencies which
|
||||
run on the platform where the new derivation will be built.
|
||||
<footnote xml:id="footnote-stdenv-native-dependencies-in-path">
|
||||
<para>
|
||||
Currently, that means for native builds all dependencies are put on the
|
||||
<envar>PATH</envar>. But in the future that may not be the case for sake
|
||||
of matching cross: the platforms would be assumed to be unique for native
|
||||
and cross builds alike, so only the <varname>depsBuild*</varname> and
|
||||
<varname>nativeBuildDependencies</varname> dependencies would affect the
|
||||
Currently, this means for native builds all dependencies are put
|
||||
on the <envar>PATH</envar>. But in the future that may not be the
|
||||
case for sake of matching cross: the platforms would be assumed
|
||||
to be unique for native and cross builds alike, so only the
|
||||
<varname>depsBuild*</varname> and
|
||||
<varname>nativeBuildInputs</varname> would be added to the
|
||||
<envar>PATH</envar>.
|
||||
</para>
|
||||
</footnote>
|
||||
@ -251,28 +252,27 @@ genericBuild
|
||||
<para>
|
||||
The dependency is propagated when it forces some of its other-transitive
|
||||
(non-immediate) downstream dependencies to also take it on as an immediate
|
||||
dependency. Nix itself already takes a package's transitive dependencies
|
||||
into account, but this propagation ensures nixpkgs-specific infrastructure
|
||||
like setup hooks (mentioned above) also are run as if the propagated
|
||||
dependency.
|
||||
dependency. Nix itself already takes a package's transitive dependencies into
|
||||
account, but this propagation ensures nixpkgs-specific infrastructure like
|
||||
setup hooks (mentioned above) also are run as if the propagated dependency.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is important to note dependencies are not necessary propagated as the
|
||||
same sort of dependency that they were before, but rather as the
|
||||
It is important to note that dependencies are not necessarily propagated as
|
||||
the same sort of dependency that they were before, but rather as the
|
||||
corresponding sort so that the platform rules still line up. The exact rules
|
||||
for dependency propagation can be given by assigning each sort of dependency
|
||||
two integers based one how it's host and target platforms are offset from
|
||||
the depending derivation's platforms. Those offsets are given are given
|
||||
below in the descriptions of each dependency list attribute.
|
||||
Algorithmically, we traverse propagated inputs, accumulating every
|
||||
propagated dep's propagated deps and adjusting them to account for the
|
||||
"shift in perspective" described by the current dep's platform offsets. This
|
||||
results in sort a transitive closure of the dependency relation, with the
|
||||
offsets being approximately summed when two dependency links are combined.
|
||||
We also prune transitive deps whose combined offsets go out-of-bounds, which
|
||||
can be viewed as a filter over that transitive closure removing dependencies
|
||||
that are blatantly absurd.
|
||||
for dependency propagation can be given by assigning to each dependency two
|
||||
integers based one how its host and target platforms are offset from the
|
||||
depending derivation's platforms. Those offsets are given below in the
|
||||
descriptions of each dependency list attribute. Algorithmically, we traverse
|
||||
propagated inputs, accumulating every propagated dependency's propagated
|
||||
dependencies and adjusting them to account for the "shift in perspective"
|
||||
described by the current dependency's platform offsets. This results in sort
|
||||
a transitive closure of the dependency relation, with the offsets being
|
||||
approximately summed when two dependency links are combined. We also prune
|
||||
transitive dependencies whose combined offsets go out-of-bounds, which can be
|
||||
viewed as a filter over that transitive closure removing dependencies that
|
||||
are blatantly absurd.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -287,8 +287,8 @@ genericBuild
|
||||
propagation logic.
|
||||
</para>
|
||||
</footnote>
|
||||
They're confusing in very different ways so...hopefully if something doesn't
|
||||
make sense in one presentation, it does in the other!
|
||||
They're confusing in very different ways so... hopefully if something doesn't
|
||||
make sense in one presentation, it will in the other!
|
||||
<programlisting>
|
||||
let mapOffset(h, t, i) = i + (if i <= 0 then h else t - 1)
|
||||
|
||||
@ -307,13 +307,13 @@ dep(h0, _, A, B)
|
||||
propagated-dep(h1, t1, B, C)
|
||||
h0 + h1 in {-1, 0, 1}
|
||||
h0 + t1 in {-1, 0, -1}
|
||||
-------------------------------------- Take immediate deps' propagated deps
|
||||
----------------------------- Take immediate dependencies' propagated dependencies
|
||||
propagated-dep(mapOffset(h0, t0, h1),
|
||||
mapOffset(h0, t0, t1),
|
||||
A, C)</programlisting>
|
||||
<programlisting>
|
||||
propagated-dep(h, t, A, B)
|
||||
-------------------------------------- Propagated deps count as deps
|
||||
----------------------------- Propagated dependencies count as dependencies
|
||||
dep(h, t, A, B)</programlisting>
|
||||
Some explanation of this monstrosity is in order. In the common case, the
|
||||
target offset of a dependency is the successor to the target offset:
|
||||
@ -324,31 +324,31 @@ let f(h, h + 1, i) = i + (if i <= 0 then h else (h + 1) - 1)
|
||||
let f(h, h + 1, i) = i + (if i <= 0 then h else h)
|
||||
let f(h, h + 1, i) = i + h
|
||||
</programlisting>
|
||||
This is where the "sum-like" comes from above: We can just sum all the host
|
||||
offset to get the host offset of the transitive dependency. The target
|
||||
offset is the transitive dep is simply the host offset + 1, just as it was
|
||||
with the dependencies composed to make this transitive one; it can be
|
||||
This is where "sum-like" comes in from above: We can just sum all of the host
|
||||
offsets to get the host offset of the transitive dependency. The target
|
||||
offset is the transitive dependency is simply the host offset + 1, just as it
|
||||
was with the dependencies composed to make this transitive one; it can be
|
||||
ignored as it doesn't add any new information.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Because of the bounds checks, the uncommon cases are <literal>h =
|
||||
t</literal> and <literal>h + 2 = t</literal>. In the former case, the
|
||||
motivation for <function>mapOffset</function> is that since its host and
|
||||
target platforms are the same, no transitive dep of it should be able to
|
||||
"discover" an offset greater than its reduced target offsets.
|
||||
Because of the bounds checks, the uncommon cases are <literal>h = t</literal>
|
||||
and <literal>h + 2 = t</literal>. In the former case, the motivation for
|
||||
<function>mapOffset</function> is that since its host and target platforms
|
||||
are the same, no transitive dependency of it should be able to "discover" an
|
||||
offset greater than its reduced target offsets.
|
||||
<function>mapOffset</function> effectively "squashes" all its transitive
|
||||
dependencies' offsets so that none will ever be greater than the target
|
||||
offset of the original <literal>h = t</literal> package. In the other case,
|
||||
<literal>h + 1</literal> is skipped over between the host and target
|
||||
offsets. Instead of squashing the offsets, we need to "rip" them apart so no
|
||||
<literal>h + 1</literal> is skipped over between the host and target offsets.
|
||||
Instead of squashing the offsets, we need to "rip" them apart so no
|
||||
transitive dependencies' offset is that one.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Overall, the unifying theme here is that propagation shouldn't be
|
||||
introducing transitive dependencies involving platforms the needing package
|
||||
is unaware of. The offset bounds checking and definition of
|
||||
Overall, the unifying theme here is that propagation shouldn't be introducing
|
||||
transitive dependencies involving platforms the depending package is unaware
|
||||
of. The offset bounds checking and definition of
|
||||
<function>mapOffset</function> together ensure that this is the case.
|
||||
Discovering a new offset is discovering a new platform, and since those
|
||||
platforms weren't in the derivation "spec" of the needing package, they
|
||||
@ -369,20 +369,20 @@ let f(h, h + 1, i) = i + h
|
||||
A list of dependencies whose host and target platforms are the new
|
||||
derivation's build platform. This means a <literal>-1</literal> host and
|
||||
<literal>-1</literal> target offset from the new derivation's platforms.
|
||||
They are programs/libraries used at build time that furthermore produce
|
||||
programs/libraries also used at build time. If the dependency doesn't
|
||||
care about the target platform (i.e. isn't a compiler or similar tool),
|
||||
put it in <varname>nativeBuildInputs</varname>instead. The most common
|
||||
use for this <literal>buildPackages.stdenv.cc</literal>, the default C
|
||||
compiler for this role. That example crops up more than one might think
|
||||
in old commonly used C libraries.
|
||||
These are programs and libraries used at build time that produce programs
|
||||
and libraries also used at build time. If the dependency doesn't care
|
||||
about the target platform (i.e. isn't a compiler or similar tool), put it
|
||||
in <varname>nativeBuildInputs</varname> instead. The most common use of
|
||||
this <literal>buildPackages.stdenv.cc</literal>, the default C compiler
|
||||
for this role. That example crops up more than one might think in old
|
||||
commonly used C libraries.
|
||||
</para>
|
||||
<para>
|
||||
Since these packages are able to be run at build time, that are always
|
||||
Since these packages are able to be run at build-time, they are always
|
||||
added to the <envar>PATH</envar>, as described above. But since these
|
||||
packages are only guaranteed to be able to run then, they shouldn't
|
||||
persist as run-time dependencies. This isn't currently enforced, but
|
||||
could be in the future.
|
||||
persist as run-time dependencies. This isn't currently enforced, but could
|
||||
be in the future.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -395,21 +395,20 @@ let f(h, h + 1, i) = i + h
|
||||
A list of dependencies whose host platform is the new derivation's build
|
||||
platform, and target platform is the new derivation's host platform. This
|
||||
means a <literal>-1</literal> host offset and <literal>0</literal> target
|
||||
offset from the new derivation's platforms. They are programs/libraries
|
||||
used at build time that, if they are a compiler or similar tool, produce
|
||||
code to run at run time—i.e. tools used to build the new derivation. If
|
||||
the dependency doesn't care about the target platform (i.e. isn't a
|
||||
compiler or similar tool), put it here, rather than in
|
||||
offset from the new derivation's platforms. These are programs and
|
||||
libraries used at build-time that, if they are a compiler or similar tool,
|
||||
produce code to run at run-time—i.e. tools used to build the new
|
||||
derivation. If the dependency doesn't care about the target platform (i.e.
|
||||
isn't a compiler or similar tool), put it here, rather than in
|
||||
<varname>depsBuildBuild</varname> or <varname>depsBuildTarget</varname>.
|
||||
This would be called <varname>depsBuildHost</varname> but for historical
|
||||
continuity.
|
||||
This could be called <varname>depsBuildHost</varname> but
|
||||
<varname>nativeBuildInputs</varname> is used for historical continuity.
|
||||
</para>
|
||||
<para>
|
||||
Since these packages are able to be run at build time, that are added to
|
||||
the <envar>PATH</envar>, as described above. But since these packages
|
||||
only are guaranteed to be able to run then, they shouldn't persist as
|
||||
run-time dependencies. This isn't currently enforced, but could be in the
|
||||
future.
|
||||
Since these packages are able to be run at build-time, they are added to
|
||||
the <envar>PATH</envar>, as described above. But since these packages are
|
||||
only guaranteed to be able to run then, they shouldn't persist as run-time
|
||||
dependencies. This isn't currently enforced, but could be in the future.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -422,34 +421,33 @@ let f(h, h + 1, i) = i + h
|
||||
A list of dependencies whose host platform is the new derivation's build
|
||||
platform, and target platform is the new derivation's target platform.
|
||||
This means a <literal>-1</literal> host offset and <literal>1</literal>
|
||||
target offset from the new derivation's platforms. They are programs used
|
||||
at build time that produce code to run at run with code produced by the
|
||||
depending package. Most commonly, these would tools used to build the
|
||||
runtime or standard library the currently-being-built compiler will
|
||||
inject into any code it compiles. In many cases, the currently-being
|
||||
built compiler is itself employed for that task, but when that compiler
|
||||
won't run (i.e. its build and host platform differ) this is not possible.
|
||||
Other times, the compiler relies on some other tool, like binutils, that
|
||||
is always built separately so the dependency is unconditional.
|
||||
target offset from the new derivation's platforms. These are programs used
|
||||
at build time that produce code to run with code produced by the depending
|
||||
package. Most commonly, these are tools used to build the runtime or
|
||||
standard library that the currently-being-built compiler will inject into
|
||||
any code it compiles. In many cases, the currently-being-built-compiler is
|
||||
itself employed for that task, but when that compiler won't run (i.e. its
|
||||
build and host platform differ) this is not possible. Other times, the
|
||||
compiler relies on some other tool, like binutils, that is always built
|
||||
separately so that the dependency is unconditional.
|
||||
</para>
|
||||
<para>
|
||||
This is a somewhat confusing dependency to wrap ones head around, and for
|
||||
good reason. As the only one where the platform offsets are not adjacent
|
||||
integers, it requires thinking of a bootstrapping stage
|
||||
<emphasis>two</emphasis> away from the current one. It and it's use-case
|
||||
go hand in hand and are both considered poor form: try not to need this
|
||||
sort dependency, and try not avoid building standard libraries / runtimes
|
||||
This is a somewhat confusing concept to wrap one’s head around, and for
|
||||
good reason. As the only dependency type where the platform offsets are
|
||||
not adjacent integers, it requires thinking of a bootstrapping stage
|
||||
<emphasis>two</emphasis> away from the current one. It and its use-case go
|
||||
hand in hand and are both considered poor form: try to not need this sort
|
||||
of dependency, and try to avoid building standard libraries and runtimes
|
||||
in the same derivation as the compiler produces code using them. Instead
|
||||
strive to build those like a normal library, using the newly-built
|
||||
compiler just as a normal library would. In short, do not use this
|
||||
attribute unless you are packaging a compiler and are sure it is needed.
|
||||
</para>
|
||||
<para>
|
||||
Since these packages are able to be run at build time, that are added to
|
||||
the <envar>PATH</envar>, as described above. But since these packages
|
||||
only are guaranteed to be able to run then, they shouldn't persist as
|
||||
run-time dependencies. This isn't currently enforced, but could be in the
|
||||
future.
|
||||
Since these packages are able to run at build time, they are added to the
|
||||
<envar>PATH</envar>, as described above. But since these packages are only
|
||||
guaranteed to be able to run then, they shouldn't persist as run-time
|
||||
dependencies. This isn't currently enforced, but could be in the future.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -460,15 +458,15 @@ let f(h, h + 1, i) = i + h
|
||||
<listitem>
|
||||
<para>
|
||||
A list of dependencies whose host and target platforms match the new
|
||||
derivation's host platform. This means a both <literal>0</literal> host
|
||||
offset and <literal>0</literal> target offset from the new derivation's
|
||||
host platform. These are packages used at run-time to generate code also
|
||||
used at run-time. In practice, that would usually be tools used by
|
||||
compilers for metaprogramming/macro systems, or libraries used by the
|
||||
macros/metaprogramming code itself. It's always preferable to use a
|
||||
<varname>depsBuildBuild</varname> dependency in the derivation being
|
||||
built than a <varname>depsHostHost</varname> on the tool doing the
|
||||
building for this purpose.
|
||||
derivation's host platform. This means a <literal>0</literal> host offset
|
||||
and <literal>0</literal> target offset from the new derivation's host
|
||||
platform. These are packages used at run-time to generate code also used
|
||||
at run-time. In practice, this would usually be tools used by compilers
|
||||
for macros or a metaprogramming system, or libraries used by the macros or
|
||||
metaprogramming code itself. It's always preferable to use a
|
||||
<varname>depsBuildBuild</varname> dependency in the derivation being built
|
||||
over a <varname>depsHostHost</varname> on the tool doing the building for
|
||||
this purpose.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -479,20 +477,20 @@ let f(h, h + 1, i) = i + h
|
||||
<listitem>
|
||||
<para>
|
||||
A list of dependencies whose host platform and target platform match the
|
||||
new derivation's. This means a <literal>0</literal> host offset and
|
||||
new derivation's. This means a <literal>0</literal> host offset and a
|
||||
<literal>1</literal> target offset from the new derivation's host
|
||||
platform. This would be called <varname>depsHostTarget</varname> but for
|
||||
historical continuity. If the dependency doesn't care about the target
|
||||
platform (i.e. isn't a compiler or similar tool), put it here, rather
|
||||
than in <varname>depsBuildBuild</varname>.
|
||||
platform (i.e. isn't a compiler or similar tool), put it here, rather than
|
||||
in <varname>depsBuildBuild</varname>.
|
||||
</para>
|
||||
<para>
|
||||
These often are programs/libraries used by the new derivation at
|
||||
These are often programs and libraries used by the new derivation at
|
||||
<emphasis>run</emphasis>-time, but that isn't always the case. For
|
||||
example, the machine code in a statically linked library is only used at
|
||||
run time, but the derivation containing the library is only needed at
|
||||
build time. Even in the dynamic case, the library may also be needed at
|
||||
build time to appease the linker.
|
||||
example, the machine code in a statically-linked library is only used at
|
||||
run-time, but the derivation containing the library is only needed at
|
||||
build-time. Even in the dynamic case, the library may also be needed at
|
||||
build-time to appease the linker.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -581,7 +579,7 @@ let f(h, h + 1, i) = i + h
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>depsTargetTarget</varname>
|
||||
<varname>depsTargetTargetPropagated</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
@ -604,10 +602,10 @@ let f(h, h + 1, i) = i + h
|
||||
<listitem>
|
||||
<para>
|
||||
A natural number indicating how much information to log. If set to 1 or
|
||||
higher, <literal>stdenv</literal> will print moderate debug information
|
||||
during the build. In particular, the <command>gcc</command> and
|
||||
<command>ld</command> wrapper scripts will print out the complete command
|
||||
line passed to the wrapped tools. If set to 6 or higher, the
|
||||
higher, <literal>stdenv</literal> will print moderate debugging
|
||||
information during the build. In particular, the <command>gcc</command>
|
||||
and <command>ld</command> wrapper scripts will print out the complete
|
||||
command line passed to the wrapped tools. 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
|
||||
@ -618,7 +616,7 @@ let f(h, h + 1, i) = i + h
|
||||
</variablelist>
|
||||
|
||||
<variablelist>
|
||||
<title>Variables affecting build properties</title>
|
||||
<title>Attributes affecting build properties</title>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>enableParallelBuilding</varname>
|
||||
@ -637,21 +635,6 @@ let f(h, h + 1, i) = i + h
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>preferLocalBuild</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
If set, specifies that the package is so lightweight in terms of build
|
||||
operations (e.g. write a text file from a Nix string to the store) that
|
||||
there's no need to look for it in binary caches -- it's faster to just
|
||||
build it locally. It also tells Hydra and other facilities that this
|
||||
package doesn't need to be exported in binary caches (noone would use it,
|
||||
after all).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<variablelist>
|
||||
@ -681,11 +664,47 @@ passthru = {
|
||||
<literal>hello.baz.value1</literal>. We don't specify any usage or schema
|
||||
of <literal>passthru</literal> - it is meant for values that would be
|
||||
useful outside the derivation in other parts of a Nix expression (e.g. in
|
||||
other derivations). An example would be to convey some specific
|
||||
dependency of your derivation which contains a program with plugins
|
||||
support. Later, others who make derivations with plugins can use
|
||||
passed-through dependency to ensure that their plugin would be
|
||||
binary-compatible with built program.
|
||||
other derivations). An example would be to convey some specific dependency
|
||||
of your derivation which contains a program with plugins support. Later,
|
||||
others who make derivations with plugins can use passed-through dependency
|
||||
to ensure that their plugin would be binary-compatible with built program.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>passthru.updateScript</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A script to be run by <filename>maintainers/scripts/update.nix</filename> when
|
||||
the package is matched. It needs to be an executable file, either on the file
|
||||
system:
|
||||
<programlisting>
|
||||
passthru.updateScript = ./update.sh;
|
||||
</programlisting>
|
||||
or inside the expression itself:
|
||||
<programlisting>
|
||||
passthru.updateScript = writeScript "update-zoom-us" ''
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p curl pcre common-updater-scripts
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
version="$(curl -sI https://zoom.us/client/latest/zoom_x86_64.tar.xz | grep -Fi 'Location:' | pcregrep -o1 '/(([0-9]\.?)+)/')"
|
||||
update-source-version zoom-us "$version"
|
||||
'';
|
||||
</programlisting>
|
||||
The attribute can also contain a list, a script followed by arguments to be passed to it:
|
||||
<programlisting>
|
||||
passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ];
|
||||
</programlisting>
|
||||
Note that the update scripts will be run in parallel by default; you should avoid running <command>git commit</command> or any other commands that cannot handle that.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For information about how to run the updates, execute
|
||||
<cmdsynopsis><command>nix-shell</command> <arg>maintainers/scripts/update.nix</arg></cmdsynopsis>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -851,7 +870,7 @@ passthru = {
|
||||
<para>
|
||||
Zip files are unpacked using <command>unzip</command>. However,
|
||||
<command>unzip</command> is not in the standard environment, so you
|
||||
should add it to <varname>buildInputs</varname> yourself.
|
||||
should add it to <varname>nativeBuildInputs</varname> yourself.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -1091,6 +1110,17 @@ passthru = {
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>prefixKey</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The key to use when specifying the prefix. By default, this is set to
|
||||
<option>--prefix=</option> as that is used by the majority of packages.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>dontAddDisableDepTrack</varname>
|
||||
@ -1148,12 +1178,11 @@ passthru = {
|
||||
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.
|
||||
or a subset to control exactly which platform flags are passed. Compilers
|
||||
and other tools can use this to also pass the target platform.
|
||||
<footnote xml:id="footnote-stdenv-build-time-guessing-impurity">
|
||||
<para>
|
||||
Eventually these will be passed when in native builds too, to improve
|
||||
Eventually these will be passed building natively as well, to improve
|
||||
determinism: build-time guessing, as is done today, is a risk of
|
||||
impurity.
|
||||
</para>
|
||||
@ -1218,17 +1247,6 @@ passthru = {
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>checkInputs</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of dependencies used by the phase. This gets included in
|
||||
<varname>buildInputs</varname> when <varname>doCheck</varname> is set.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>makeFlags</varname>
|
||||
@ -1378,6 +1396,18 @@ makeFlagsArray=(CFLAGS="-O0 -g" LDFLAGS="-lfoo -lbar")
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>checkInputs</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of dependencies used by the phase. This gets included in
|
||||
<varname>nativeBuildInputs</varname> when <varname>doCheck</varname> is
|
||||
set.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>preCheck</varname>
|
||||
@ -1650,13 +1680,11 @@ installTargets = "install-bin install-doc";</programlisting>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A package can export a <link
|
||||
linkend="ssec-setup-hooks">setup
|
||||
hook</link> by setting this variable. The setup hook, if defined, is
|
||||
copied to <filename>$out/nix-support/setup-hook</filename>. Environment
|
||||
variables are then substituted in it using
|
||||
<function
|
||||
linkend="fun-substituteAll">substituteAll</function>.
|
||||
A package can export a <link linkend="ssec-setup-hooks">setup hook</link>
|
||||
by setting this variable. The setup hook, if defined, is copied to
|
||||
<filename>$out/nix-support/setup-hook</filename>. Environment variables
|
||||
are then substituted in it using <function
|
||||
linkend="fun-substituteAll">substituteAll</function>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -2089,47 +2117,46 @@ someVar=$(stripHash $name)
|
||||
<title>Package setup hooks</title>
|
||||
|
||||
<para>
|
||||
Nix itself considers a build-time dependency merely something that should
|
||||
Nix itself considers a build-time dependency as merely something that should
|
||||
previously be built and accessible at build time—packages themselves are
|
||||
on their own to perform any additional setup. In most cases, that is fine,
|
||||
and the downstream derivation can deal with it's own dependencies. But for a
|
||||
and the downstream derivation can deal with its own dependencies. But for a
|
||||
few common tasks, that would result in almost every package doing the same
|
||||
sort of setup work---depending not on the package itself, but entirely on
|
||||
sort of setup work—depending not on the package itself, but entirely on
|
||||
which dependencies were used.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In order to alleviate this burden, the <firstterm>setup
|
||||
hook></firstterm>mechanism was written, where any package can include a
|
||||
shell script that [by convention rather than enforcement by Nix], any
|
||||
downstream reverse-dependency will source as part of its build process. That
|
||||
allows the downstream dependency to merely specify its dependencies, and
|
||||
lets those dependencies effectively initialize themselves. No boilerplate
|
||||
mirroring the list of dependencies is needed.
|
||||
In order to alleviate this burden, the <firstterm>setup hook</firstterm>
|
||||
mechanism was written, where any package can include a shell script that [by
|
||||
convention rather than enforcement by Nix], any downstream
|
||||
reverse-dependency will source as part of its build process. That allows the
|
||||
downstream dependency to merely specify its dependencies, and lets those
|
||||
dependencies effectively initialize themselves. No boilerplate mirroring the
|
||||
list of dependencies is needed.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The Setup hook mechanism is a bit of a sledgehammer though: a powerful
|
||||
The setup hook mechanism is a bit of a sledgehammer though: a powerful
|
||||
feature with a broad and indiscriminate area of effect. The combination of
|
||||
its power and implicit use may be expedient, but isn't without costs. Nix
|
||||
itself is unchanged, but the spirit of adding dependencies being effect-free
|
||||
itself is unchanged, but the spirit of added dependencies being effect-free
|
||||
is violated even if the letter isn't. For example, if a derivation path is
|
||||
mentioned more than once, Nix itself doesn't care and simply makes sure the
|
||||
dependency derivation is already built just the same—depending is just
|
||||
needing something to exist, and needing is idempotent. However, a dependency
|
||||
specified twice will have its setup hook run twice, and that could easily
|
||||
change the build environment (though a well-written setup hook will
|
||||
therefore strive to be idempotent so this is in fact not observable). More
|
||||
broadly, setup hooks are anti-modular in that multiple dependencies, whether
|
||||
the same or different, should not interfere and yet their setup hooks may
|
||||
well do so.
|
||||
change the build environment (though a well-written setup hook will therefore
|
||||
strive to be idempotent so this is in fact not observable). More broadly,
|
||||
setup hooks are anti-modular in that multiple dependencies, whether the same
|
||||
or different, should not interfere and yet their setup hooks may well do so.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The most typical use of the setup hook is actually to add other hooks which
|
||||
are then run (i.e. after all the setup hooks) on each dependency. For
|
||||
example, the C compiler wrapper's setup hook feeds itself flags for each
|
||||
dependency that contains relevant libaries and headers. This is done by
|
||||
dependency that contains relevant libraries and headers. This is done by
|
||||
defining a bash function, and appending its name to one of
|
||||
<envar>envBuildBuildHooks</envar>`, <envar>envBuildHostHooks</envar>`,
|
||||
<envar>envBuildTargetHooks</envar>`, <envar>envHostHostHooks</envar>`,
|
||||
@ -2141,15 +2168,14 @@ someVar=$(stripHash $name)
|
||||
<para>
|
||||
Packages adding a hook should not hard code a specific hook, but rather
|
||||
choose a variable <emphasis>relative</emphasis> to how they are included.
|
||||
Returning to the C compiler wrapper example, if it itself is an
|
||||
Returning to the C compiler wrapper example, if the wrapper itself is an
|
||||
<literal>n</literal> dependency, then it only wants to accumulate flags from
|
||||
<literal>n + 1</literal> dependencies, as only those ones match the
|
||||
compiler's target platform. The <envar>hostOffset</envar> variable is
|
||||
defined with the current dependency's host offset
|
||||
<envar>targetOffset</envar> with its target offset, before it's setup hook
|
||||
is sourced. Additionally, since most environment hooks don't care about the
|
||||
target platform, That means the setup hook can append to the right bash
|
||||
array by doing something like
|
||||
compiler's target platform. The <envar>hostOffset</envar> variable is defined
|
||||
with the current dependency's host offset <envar>targetOffset</envar> with
|
||||
its target offset, before its setup hook is sourced. Additionally, since most
|
||||
environment hooks don't care about the target platform, that means the setup
|
||||
hook can append to the right bash array by doing something like
|
||||
<programlisting language="bash">
|
||||
addEnvHooks "$hostOffset" myBashFunction
|
||||
</programlisting>
|
||||
@ -2157,7 +2183,7 @@ addEnvHooks "$hostOffset" myBashFunction
|
||||
|
||||
<para>
|
||||
The <emphasis>existence</emphasis> of setups hooks has long been documented
|
||||
and packages inside Nixpkgs are free to use these mechanism. Other packages,
|
||||
and packages inside Nixpkgs are free to use this mechanism. Other packages,
|
||||
however, should not rely on these mechanisms not changing between Nixpkgs
|
||||
versions. Because of the existing issues with this system, there's little
|
||||
benefit from mandating it be stable for any period of time.
|
||||
@ -2174,19 +2200,19 @@ addEnvHooks "$hostOffset" myBashFunction
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Bintools Wrapper wraps the binary utilities for a bunch of miscellaneous
|
||||
purposes. These are GNU Binutils when targetting Linux, and a mix of
|
||||
cctools and GNU binutils for Darwin. [The "Bintools" name is supposed to
|
||||
be a compromise between "Binutils" and "cctools" not denoting any
|
||||
specific implementation.] Specifically, the underlying bintools package,
|
||||
and a C standard library (glibc or Darwin's libSystem, just for the
|
||||
dynamic loader) are all fed in, and dependency finding, hardening (see
|
||||
below), and purity checks for each are handled by Bintools Wrapper.
|
||||
Packages typically depend on CC Wrapper, which in turn (at run time)
|
||||
depends on Bintools Wrapper.
|
||||
The Bintools Wrapper wraps the binary utilities for a bunch of
|
||||
miscellaneous purposes. These are GNU Binutils when targetting Linux, and
|
||||
a mix of cctools and GNU binutils for Darwin. [The "Bintools" name is
|
||||
supposed to be a compromise between "Binutils" and "cctools" not denoting
|
||||
any specific implementation.] Specifically, the underlying bintools
|
||||
package, and a C standard library (glibc or Darwin's libSystem, just for
|
||||
the dynamic loader) are all fed in, and dependency finding, hardening
|
||||
(see below), and purity checks for each are handled by the Bintools
|
||||
Wrapper. Packages typically depend on CC Wrapper, which in turn (at run
|
||||
time) depends on the Bintools Wrapper.
|
||||
</para>
|
||||
<para>
|
||||
Bintools Wrapper was only just recently split off from CC Wrapper, so
|
||||
The Bintools Wrapper was only just recently split off from CC Wrapper, so
|
||||
the division of labor is still being worked out. For example, it
|
||||
shouldn't care about about the C standard library, but just take a
|
||||
derivation with the dynamic loader (which happens to be the glibc on
|
||||
@ -2194,24 +2220,24 @@ addEnvHooks "$hostOffset" myBashFunction
|
||||
to need to share, and probably the most important to understand. It is
|
||||
currently accomplished by collecting directories of host-platform
|
||||
dependencies (i.e. <varname>buildInputs</varname> and
|
||||
<varname>nativeBuildInputs</varname>) in environment variables. Bintools
|
||||
Wrapper's setup hook causes any <filename>lib</filename> and
|
||||
<varname>nativeBuildInputs</varname>) in environment variables. The
|
||||
Bintools Wrapper's setup hook causes any <filename>lib</filename> and
|
||||
<filename>lib64</filename> subdirectories to be added to
|
||||
<envar>NIX_LDFLAGS</envar>. Since CC Wrapper and Bintools Wrapper use
|
||||
the same strategy, most of the Bintools Wrapper code is sparsely
|
||||
commented and refers to CC Wrapper. But CC Wrapper's code, by contrast,
|
||||
has quite lengthy comments. Bintools Wrapper merely cites those, rather
|
||||
than repeating them, to avoid falling out of sync.
|
||||
<envar>NIX_LDFLAGS</envar>. Since the CC Wrapper and the Bintools Wrapper
|
||||
use the same strategy, most of the Bintools Wrapper code is sparsely
|
||||
commented and refers to the CC Wrapper. But the CC Wrapper's code, by
|
||||
contrast, has quite lengthy comments. The Bintools Wrapper merely cites
|
||||
those, rather than repeating them, to avoid falling out of sync.
|
||||
</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
|
||||
environment variables to tell build systems which executables fulfill
|
||||
which purpose. They are defined to just be the base name of the tools,
|
||||
under the assumption that Bintools Wrapper's binaries will be on the
|
||||
under the assumption that the Bintools 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 Bintools
|
||||
<command>clang</command> is to be used. Secondly, this helps packages not
|
||||
get confused when cross-compiling, in which case multiple Bintools
|
||||
Wrappers may simultaneously be in use.
|
||||
<footnote xml:id="footnote-stdenv-per-platform-wrapper">
|
||||
<para>
|
||||
@ -2223,20 +2249,20 @@ addEnvHooks "$hostOffset" myBashFunction
|
||||
</para>
|
||||
</footnote>
|
||||
<envar>BUILD_</envar>- and <envar>TARGET_</envar>-prefixed versions of
|
||||
the normal environment variable are defined for the additional Bintools
|
||||
the normal environment variable are defined for additional Bintools
|
||||
Wrappers, properly disambiguating them.
|
||||
</para>
|
||||
<para>
|
||||
A problem with this final task is that Bintools Wrapper is honest and
|
||||
A problem with this final task is that the Bintools 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 Bintools Wrapper will break those packages, as
|
||||
LD is already defined as the actual 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>.
|
||||
only so define <envar>LD</envar> when it is undefined as a fallback. This
|
||||
triple-threat means Bintools Wrapper will break those packages, as LD is
|
||||
already defined as the actual 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>
|
||||
@ -2246,30 +2272,31 @@ addEnvHooks "$hostOffset" myBashFunction
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
CC Wrapper wraps a C toolchain for a bunch of miscellaneous purposes.
|
||||
The CC Wrapper wraps a C toolchain for a bunch of miscellaneous purposes.
|
||||
Specifically, a C compiler (GCC or Clang), wrapped binary tools, and a C
|
||||
standard library (glibc or Darwin's libSystem, just for the dynamic
|
||||
loader) are all fed in, and dependency finding, hardening (see below),
|
||||
and purity checks for each are handled by CC Wrapper. Packages typically
|
||||
depend on CC Wrapper, which in turn (at run time) depends on Bintools
|
||||
Wrapper.
|
||||
and purity checks for each are handled by the CC Wrapper. Packages
|
||||
typically depend on the CC Wrapper, which in turn (at run-time) depends
|
||||
on the Bintools Wrapper.
|
||||
</para>
|
||||
<para>
|
||||
Dependency finding is undoubtedly the main task of CC Wrapper. This
|
||||
works just like Bintools Wrapper, except that any
|
||||
Dependency finding is undoubtedly the main task of the CC Wrapper. This
|
||||
works just like the Bintools Wrapper, except that any
|
||||
<filename>include</filename> subdirectory of any relevant dependency is
|
||||
added to <envar>NIX_CFLAGS_COMPILE</envar>. The setup hook itself
|
||||
contains some lengthy comments describing the exact convoluted mechanism
|
||||
by which this is accomplished.
|
||||
</para>
|
||||
<para>
|
||||
CC Wrapper also like Bintools Wrapper defines standard environment
|
||||
variables with the names of the tools it wraps, for the same reasons
|
||||
described above. Importantly, while it includes a <command>cc</command>
|
||||
symlink to the c compiler for portability, the <envar>CC</envar> will be
|
||||
defined using the compiler's "real name" (i.e. <command>gcc</command> or
|
||||
<command>clang</command>). This helps lousy build systems that inspect
|
||||
on the name of the compiler rather than run it.
|
||||
Similarly, the CC Wrapper follows the Bintools Wrapper in defining
|
||||
standard environment variables with the names of the tools it wraps, for
|
||||
the same reasons described above. Importantly, while it includes a
|
||||
<command>cc</command> symlink to the c compiler for portability, the
|
||||
<envar>CC</envar> will be defined using the compiler's "real name" (i.e.
|
||||
<command>gcc</command> or <command>clang</command>). This helps lousy
|
||||
build systems that inspect on the name of the compiler rather than run
|
||||
it.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -2329,9 +2356,11 @@ addEnvHooks "$hostOffset" myBashFunction
|
||||
<listitem>
|
||||
<para>
|
||||
The <varname>autoreconfHook</varname> derivation adds
|
||||
<varname>autoreconfPhase</varname>, which runs autoreconf, libtoolize
|
||||
and automake, essentially preparing the configure script in
|
||||
autotools-based builds.
|
||||
<varname>autoreconfPhase</varname>, which runs autoreconf, libtoolize and
|
||||
automake, essentially preparing the configure script in autotools-based
|
||||
builds. Most autotools-based packages come with the configure script
|
||||
pre-generated, but this hook is necessary for a few packages and when you
|
||||
need to patch the package’s configure scripts.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -2375,9 +2404,9 @@ addEnvHooks "$hostOffset" myBashFunction
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Exports <envar>GDK_PIXBUF_MODULE_FILE</envar> environment variable the
|
||||
the builder. Add librsvg package to <varname>buildInputs</varname> to
|
||||
get svg support.
|
||||
Exports <envar>GDK_PIXBUF_MODULE_FILE</envar> environment variable to the
|
||||
builder. Add librsvg package to <varname>buildInputs</varname> to get svg
|
||||
support.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -2414,7 +2443,7 @@ addEnvHooks "$hostOffset" myBashFunction
|
||||
PaX flags on Linux (where it is available by default; on all other
|
||||
platforms, <varname>paxmark</varname> is a no-op). For example, to
|
||||
disable secure memory protections on the executable
|
||||
<replaceable>foo</replaceable>:
|
||||
<replaceable>foo</replaceable>
|
||||
<programlisting>
|
||||
postFixup = ''
|
||||
paxmark m $out/bin/<replaceable>foo</replaceable>
|
||||
@ -2436,16 +2465,164 @@ addEnvHooks "$hostOffset" myBashFunction
|
||||
<para>
|
||||
This is a special setup hook which helps in packaging proprietary
|
||||
software in that it automatically tries to find missing shared library
|
||||
dependencies of ELF files. All packages within the
|
||||
<envar>runtimeDependencies</envar> environment variable are
|
||||
unconditionally added to executables, which is useful for programs that
|
||||
use <citerefentry>
|
||||
<refentrytitle>dlopen</refentrytitle>
|
||||
<manvolnum>3</manvolnum> </citerefentry> to load libraries at runtime.
|
||||
dependencies of ELF files based on the given
|
||||
<varname>buildInputs</varname> and <varname>nativeBuildInputs</varname>.
|
||||
</para>
|
||||
<para>
|
||||
You can also specify a <envar>runtimeDependencies</envar> environment
|
||||
variable which lists dependencies that are unconditionally added to all
|
||||
executables.
|
||||
</para>
|
||||
<para>
|
||||
This is useful for programs that use <citerefentry>
|
||||
<refentrytitle>dlopen</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
</citerefentry> to load libraries at runtime.
|
||||
</para>
|
||||
<para>
|
||||
In certain situations you may want to run the main command
|
||||
(<command>autoPatchelf</command>) of the setup hook on a file or a set
|
||||
of directories instead of unconditionally patching all outputs. This
|
||||
can be done by setting the <envar>dontAutoPatchelf</envar> environment
|
||||
variable to a non-empty value.
|
||||
</para>
|
||||
<para>
|
||||
The <command>autoPatchelf</command> command also recognizes a
|
||||
<parameter class="command">--no-recurse</parameter> command line flag,
|
||||
which prevents it from recursing into subdirectories.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
breakpointHook
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This hook will make a build pause instead of stopping when a failure
|
||||
happens. It prevents nix from cleaning up the build environment immediately and
|
||||
allows the user to attach to a build environment using the
|
||||
<command>cntr</command> command. Upon build error it will print
|
||||
instructions on how to use <command>cntr</command>. Installing
|
||||
cntr and running the command will provide shell access to the build
|
||||
sandbox of failed build. At <filename>/var/lib/cntr</filename> the
|
||||
sandboxed filesystem is mounted. All commands and files of the system are
|
||||
still accessible within the shell. To execute commands from the sandbox
|
||||
use the cntr exec subcommand. Note that <command>cntr</command> also
|
||||
needs to be executed on the machine that is doing the build, which might
|
||||
not be the case when remote builders are enabled.
|
||||
<command>cntr</command> is only supported on Linux-based platforms. To
|
||||
use it first add <literal>cntr</literal> to your
|
||||
<literal>environment.systemPackages</literal> on NixOS or alternatively to
|
||||
the root user on non-NixOS systems. Then in the package that is supposed
|
||||
to be inspected, add <literal>breakpointHook</literal> to
|
||||
<literal>nativeBuildInputs</literal>.
|
||||
<programlisting>
|
||||
nativeBuildInputs = [ breakpointHook ];
|
||||
</programlisting>
|
||||
When a build failure happens there will be an instruction printed that
|
||||
shows how to attach with <literal>cntr</literal> to the build sandbox.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
cmake
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Overrides the default configure phase to run the CMake command. By
|
||||
default, we use the Make generator of CMake. In
|
||||
addition, dependencies are added automatically to CMAKE_PREFIX_PATH so
|
||||
that packages are correctly detected by CMake. Some additional flags
|
||||
are passed in to give similar behavior to configure-based packages. You
|
||||
can disable this hook’s behavior by setting configurePhase to a custom
|
||||
value, or by setting dontUseCmakeConfigure. cmakeFlags controls flags
|
||||
passed only to CMake. By default, parallel building is enabled as CMake
|
||||
supports parallel building almost everywhere. When Ninja is also in
|
||||
use, CMake will detect that and use the ninja generator.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
xcbuildHook
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Overrides the build and install phases to run the “xcbuild” command.
|
||||
This hook is needed when a project only comes with build files for the
|
||||
XCode build system. You can disable this behavior by setting buildPhase
|
||||
and configurePhase to a custom value. xcbuildFlags controls flags
|
||||
passed only to xcbuild.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
meson
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Overrides the configure phase to run meson to generate Ninja files. You
|
||||
can disable this behavior by setting configurePhase to a custom value,
|
||||
or by setting dontUseMesonConfigure. To run these files, you should
|
||||
accompany meson with ninja. mesonFlags controls only the flags passed
|
||||
to meson. By default, parallel building is enabled as Meson supports
|
||||
parallel building almost everywhere.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
ninja
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Overrides the build, install, and check phase to run ninja instead of
|
||||
make. You can disable this behavior with the dontUseNinjaBuild,
|
||||
dontUseNinjaInstall, and dontUseNinjaCheck, respectively. Parallel
|
||||
building is enabled by default in Ninja.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
unzip
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
This setup hook will allow you to unzip .zip files specified in $src.
|
||||
There are many similar packages like unrar, undmg, etc.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
wafHook
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Overrides the configure, build, and install phases. This will run the
|
||||
"waf" script used by many projects. If waf doesn’t exist, it will copy
|
||||
the version of waf available in Nixpkgs wafFlags can be used to pass
|
||||
flags to the waf script.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
scons
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Overrides the build, install, and check phases. This uses the scons
|
||||
build system as a replacement for make. scons does not provide a
|
||||
configure phase, so everything is managed at build and install time.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="sec-purity-in-nixpkgs">
|
||||
|
44
lib/asserts.nix
Normal file
44
lib/asserts.nix
Normal file
@ -0,0 +1,44 @@
|
||||
{ lib }:
|
||||
|
||||
rec {
|
||||
|
||||
/* Print a trace message if pred is false.
|
||||
Intended to be used to augment asserts with helpful error messages.
|
||||
|
||||
Example:
|
||||
assertMsg false "nope"
|
||||
=> false
|
||||
stderr> trace: nope
|
||||
|
||||
assert (assertMsg ("foo" == "bar") "foo is not bar, silly"); ""
|
||||
stderr> trace: foo is not bar, silly
|
||||
stderr> assert failed at …
|
||||
|
||||
Type:
|
||||
assertMsg :: Bool -> String -> Bool
|
||||
*/
|
||||
# TODO(Profpatsch): add tests that check stderr
|
||||
assertMsg = pred: msg:
|
||||
if pred
|
||||
then true
|
||||
else builtins.trace msg false;
|
||||
|
||||
/* Specialized `assertMsg` for checking if val is one of the elements
|
||||
of a list. Useful for checking enums.
|
||||
|
||||
Example:
|
||||
let sslLibrary = "libressl"
|
||||
in assertOneOf "sslLibrary" sslLibrary [ "openssl" "bearssl" ]
|
||||
=> false
|
||||
stderr> trace: sslLibrary must be one of "openssl", "bearssl", but is: "libressl"
|
||||
|
||||
Type:
|
||||
assertOneOf :: String -> ComparableVal -> List ComparableVal -> Bool
|
||||
*/
|
||||
assertOneOf = name: val: xs: assertMsg
|
||||
(lib.elem val xs)
|
||||
"${name} must be one of ${
|
||||
lib.generators.toPretty {} xs}, but is: ${
|
||||
lib.generators.toPretty {} val}";
|
||||
|
||||
}
|
@ -94,6 +94,15 @@ rec {
|
||||
attrValues = builtins.attrValues or (attrs: attrVals (attrNames attrs) attrs);
|
||||
|
||||
|
||||
/* Given a set of attribute names, return the set of the corresponding
|
||||
attributes from the given set.
|
||||
|
||||
Example:
|
||||
getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; }
|
||||
=> { a = 1; b = 2; }
|
||||
*/
|
||||
getAttrs = names: attrs: genAttrs names (name: attrs.${name});
|
||||
|
||||
/* Collect each attribute named `attr' from a list of attribute
|
||||
sets. Sets that don't contain the named attribute are ignored.
|
||||
|
||||
@ -435,12 +444,15 @@ rec {
|
||||
useful for deep-overriding.
|
||||
|
||||
Example:
|
||||
x = { a = { b = 4; c = 3; }; }
|
||||
overrideExisting x { a = { b = 6; d = 2; }; }
|
||||
=> { a = { b = 6; d = 2; }; }
|
||||
overrideExisting {} { a = 1; }
|
||||
=> {}
|
||||
overrideExisting { b = 2; } { a = 1; }
|
||||
=> { b = 2; }
|
||||
overrideExisting { a = 3; b = 2; } { a = 1; }
|
||||
=> { a = 1; b = 2; }
|
||||
*/
|
||||
overrideExisting = old: new:
|
||||
old // listToAttrs (map (attr: nameValuePair attr (attrByPath [attr] old.${attr} new)) (attrNames old));
|
||||
mapAttrs (name: value: new.${name} or value) old;
|
||||
|
||||
/* Get a package output.
|
||||
If no output is found, fallback to `.out` and then to the default.
|
||||
|
@ -196,7 +196,7 @@ rec {
|
||||
newScope = scope: newScope (self // scope);
|
||||
callPackage = self.newScope {};
|
||||
overrideScope = g: lib.warn
|
||||
"`overrideScope` (from `lib.makeScope`) is deprecated. Do `overrideScope' (self: self: { … })` instead of `overrideScope (super: self: { … })`. All other overrides have the parameters in that order, including other definitions of `overrideScope`. This was the only definition violating the pattern."
|
||||
"`overrideScope` (from `lib.makeScope`) is deprecated. Do `overrideScope' (self: super: { … })` instead of `overrideScope (super: self: { … })`. All other overrides have the parameters in that order, including other definitions of `overrideScope`. This was the only definition violating the pattern."
|
||||
(makeScope newScope (lib.fixedPoints.extends (lib.flip g) f));
|
||||
overrideScope' = g: makeScope newScope (lib.fixedPoints.extends g f);
|
||||
packages = f;
|
||||
|
@ -23,27 +23,54 @@ rec {
|
||||
|
||||
# -- TRACING --
|
||||
|
||||
/* Trace msg, but only if pred is true.
|
||||
/* Conditionally trace the supplied message, based on a predicate.
|
||||
|
||||
Type: traceIf :: bool -> string -> a -> a
|
||||
|
||||
Example:
|
||||
traceIf true "hello" 3
|
||||
trace: hello
|
||||
=> 3
|
||||
*/
|
||||
traceIf = pred: msg: x: if pred then trace msg x else x;
|
||||
traceIf =
|
||||
# Predicate to check
|
||||
pred:
|
||||
# Message that should be traced
|
||||
msg:
|
||||
# Value to return
|
||||
x: if pred then trace msg x else x;
|
||||
|
||||
/* Trace the value and also return it.
|
||||
/* Trace the supplied value after applying a function to it, and
|
||||
return the original value.
|
||||
|
||||
Type: traceValFn :: (a -> b) -> a -> a
|
||||
|
||||
Example:
|
||||
traceValFn (v: "mystring ${v}") "foo"
|
||||
trace: mystring foo
|
||||
=> "foo"
|
||||
*/
|
||||
traceValFn = f: x: trace (f x) x;
|
||||
traceValFn =
|
||||
# Function to apply
|
||||
f:
|
||||
# Value to trace and return
|
||||
x: trace (f x) x;
|
||||
|
||||
/* Trace the supplied value and return it.
|
||||
|
||||
Type: traceVal :: a -> a
|
||||
|
||||
Example:
|
||||
traceVal 42
|
||||
# trace: 42
|
||||
=> 42
|
||||
*/
|
||||
traceVal = traceValFn id;
|
||||
|
||||
/* `builtins.trace`, but the value is `builtins.deepSeq`ed first.
|
||||
|
||||
Type: traceSeq :: a -> b -> b
|
||||
|
||||
Example:
|
||||
trace { a.b.c = 3; } null
|
||||
trace: { a = <CODE>; }
|
||||
@ -52,7 +79,11 @@ rec {
|
||||
trace: { a = { b = { c = 3; }; }; }
|
||||
=> null
|
||||
*/
|
||||
traceSeq = x: y: trace (builtins.deepSeq x x) y;
|
||||
traceSeq =
|
||||
# The value to trace
|
||||
x:
|
||||
# The value to return
|
||||
y: trace (builtins.deepSeq x x) y;
|
||||
|
||||
/* Like `traceSeq`, but only evaluate down to depth n.
|
||||
This is very useful because lots of `traceSeq` usages
|
||||
@ -76,27 +107,49 @@ rec {
|
||||
in trace (generators.toPretty { allowPrettyValues = true; }
|
||||
(modify depth snip x)) y;
|
||||
|
||||
/* A combination of `traceVal` and `traceSeq` */
|
||||
traceValSeqFn = f: v: traceValFn f (builtins.deepSeq v v);
|
||||
/* A combination of `traceVal` and `traceSeq` that applies a
|
||||
provided function to the value to be traced after `deepSeq`ing
|
||||
it.
|
||||
*/
|
||||
traceValSeqFn =
|
||||
# Function to apply
|
||||
f:
|
||||
# Value to trace
|
||||
v: traceValFn f (builtins.deepSeq v v);
|
||||
|
||||
/* A combination of `traceVal` and `traceSeq`. */
|
||||
traceValSeq = traceValSeqFn id;
|
||||
|
||||
/* A combination of `traceVal` and `traceSeqN` that applies a
|
||||
provided function to the value to be traced. */
|
||||
traceValSeqNFn =
|
||||
# Function to apply
|
||||
f:
|
||||
depth:
|
||||
# Value to trace
|
||||
v: traceSeqN depth (f v) v;
|
||||
|
||||
/* A combination of `traceVal` and `traceSeqN`. */
|
||||
traceValSeqNFn = f: depth: v: traceSeqN depth (f v) v;
|
||||
traceValSeqN = traceValSeqNFn id;
|
||||
|
||||
|
||||
# -- TESTING --
|
||||
|
||||
/* Evaluate a set of tests. A test is an attribute set {expr,
|
||||
expected}, denoting an expression and its expected result. The
|
||||
result is a list of failed tests, each represented as {name,
|
||||
expected, actual}, denoting the attribute name of the failing
|
||||
test and its expected and actual results. Used for regression
|
||||
testing of the functions in lib; see tests.nix for an example.
|
||||
Only tests having names starting with "test" are run.
|
||||
Add attr { tests = ["testName"]; } to run these test only
|
||||
/* Evaluate a set of tests. A test is an attribute set `{expr,
|
||||
expected}`, denoting an expression and its expected result. The
|
||||
result is a list of failed tests, each represented as `{name,
|
||||
expected, actual}`, denoting the attribute name of the failing
|
||||
test and its expected and actual results.
|
||||
|
||||
Used for regression testing of the functions in lib; see
|
||||
tests.nix for an example. Only tests having names starting with
|
||||
"test" are run.
|
||||
|
||||
Add attr { tests = ["testName"]; } to run these tests only.
|
||||
*/
|
||||
runTests = tests: lib.concatLists (lib.attrValues (lib.mapAttrs (name: test:
|
||||
runTests =
|
||||
# Tests to run
|
||||
tests: lib.concatLists (lib.attrValues (lib.mapAttrs (name: test:
|
||||
let testsToRun = if tests ? tests then tests.tests else [];
|
||||
in if (substring 0 4 name == "test" || elem name testsToRun)
|
||||
&& ((testsToRun == []) || elem name tests.tests)
|
||||
@ -105,8 +158,11 @@ rec {
|
||||
then [ { inherit name; expected = test.expected; result = test.expr; } ]
|
||||
else [] ) tests));
|
||||
|
||||
# create a test assuming that list elements are true
|
||||
# usage: { testX = allTrue [ true ]; }
|
||||
/* Create a test assuming that list elements are `true`.
|
||||
|
||||
Example:
|
||||
{ testX = allTrue [ true ]; }
|
||||
*/
|
||||
testAllTrue = expr: { inherit expr; expected = map (x: true) expr; };
|
||||
|
||||
|
||||
|
@ -38,10 +38,11 @@ let
|
||||
systems = callLibs ./systems;
|
||||
|
||||
# misc
|
||||
asserts = callLibs ./asserts.nix;
|
||||
debug = callLibs ./debug.nix;
|
||||
|
||||
generators = callLibs ./generators.nix;
|
||||
misc = callLibs ./deprecated.nix;
|
||||
|
||||
# domain-specific
|
||||
fetchers = callLibs ./fetchers.nix;
|
||||
|
||||
@ -60,11 +61,10 @@ let
|
||||
boolToString mergeAttrs flip mapNullable inNixShell min max
|
||||
importJSON warn info nixpkgsVersion version mod compare
|
||||
splitByAndCompare functionArgs setFunctionArgs isFunction;
|
||||
|
||||
inherit (fixedPoints) fix fix' extends composeExtensions
|
||||
inherit (fixedPoints) fix fix' converge extends composeExtensions
|
||||
makeExtensible makeExtensibleWithCustomName;
|
||||
inherit (attrsets) attrByPath hasAttrByPath setAttrByPath
|
||||
getAttrFromPath attrVals attrValues catAttrs filterAttrs
|
||||
getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs
|
||||
filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs
|
||||
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
|
||||
genAttrs isDerivation toDerivation optionalAttrs
|
||||
@ -117,6 +117,8 @@ let
|
||||
unknownModule mkOption;
|
||||
inherit (types) isType setType defaultTypeMerge defaultFunctor
|
||||
isOptionType mkOptionType;
|
||||
inherit (asserts)
|
||||
assertMsg assertOneOf;
|
||||
inherit (debug) addErrorContextToAttrs traceIf traceVal traceValFn
|
||||
traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq
|
||||
traceValSeqFn traceValSeqN traceValSeqNFn traceShowVal
|
||||
|
@ -24,6 +24,16 @@ rec {
|
||||
# for a concrete example.
|
||||
fix' = f: let x = f x // { __unfix__ = f; }; in x;
|
||||
|
||||
# Return the fixpoint that `f` converges to when called recursively, starting
|
||||
# with the input `x`.
|
||||
#
|
||||
# nix-repl> converge (x: x / 2) 16
|
||||
# 0
|
||||
converge = f: x:
|
||||
if (f x) == x
|
||||
then x
|
||||
else converge f (f x);
|
||||
|
||||
# Modify the contents of an explicitly recursive attribute set in a way that
|
||||
# honors `self`-references. This is accomplished with a function
|
||||
#
|
||||
@ -41,6 +51,18 @@ rec {
|
||||
# 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.
|
||||
#
|
||||
# To get a better understanding how `extends` turns a function with a fix
|
||||
# point (the package set we start with) into a new function with a different fix
|
||||
# point (the desired packages set) lets just see, how `extends g f`
|
||||
# unfolds with `g` and `f` defined above:
|
||||
#
|
||||
# extends g f = self: let super = f self; in super // g self super;
|
||||
# = self: let super = { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; }; in super // g self super
|
||||
# = self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; } // g self { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; }
|
||||
# = self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; } // { foo = "foo" + " + "; }
|
||||
# = self: { foo = "foo + "; bar = "bar"; foobar = self.foo + self.bar; }
|
||||
#
|
||||
extends = f: rattrs: self: let super = rattrs self; in super // f self super;
|
||||
|
||||
# Compose two extending functions of the type expected by 'extends'
|
||||
|
@ -143,6 +143,7 @@ rec {
|
||||
}@args: v: with builtins;
|
||||
let isPath = v: typeOf v == "path";
|
||||
in if isInt v then toString v
|
||||
else if isFloat v then "~${toString v}"
|
||||
else if isString v then ''"${libStr.escape [''"''] v}"''
|
||||
else if true == v then "true"
|
||||
else if false == v then "false"
|
||||
|
@ -13,6 +13,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
* add it to this list. The URL mentioned above is a good source for inspiration.
|
||||
*/
|
||||
|
||||
abstyles = spdx {
|
||||
spdxId = "Abstyles";
|
||||
fullName = "Abstyles License";
|
||||
};
|
||||
|
||||
afl21 = spdx {
|
||||
spdxId = "AFL-2.1";
|
||||
fullName = "Academic Free License v2.1";
|
||||
@ -42,6 +47,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
amd = {
|
||||
fullName = "AMD License Agreement";
|
||||
url = http://developer.amd.com/amd-license-agreement/;
|
||||
free = false;
|
||||
};
|
||||
|
||||
apsl20 = spdx {
|
||||
@ -99,14 +105,10 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
fullName = ''BSD 4-clause "Original" or "Old" License'';
|
||||
};
|
||||
|
||||
bsl10 = {
|
||||
fullName = "Business Source License 1.0";
|
||||
url = https://mariadb.com/bsl10;
|
||||
};
|
||||
|
||||
bsl11 = {
|
||||
fullName = "Business Source License 1.1";
|
||||
url = https://mariadb.com/bsl11;
|
||||
free = false;
|
||||
};
|
||||
|
||||
clArtistic = spdx {
|
||||
@ -309,6 +311,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
fullName = "GNU General Public License v2.0 only";
|
||||
};
|
||||
|
||||
gpl2Classpath = {
|
||||
spdxId = "GPL-2.0-with-classpath-exception";
|
||||
fullName = "GNU General Public License v2.0 only (with Classpath exception)";
|
||||
url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
|
||||
};
|
||||
|
||||
gpl2ClasspathPlus = {
|
||||
fullName = "GNU General Public License v2.0 or later (with Classpath exception)";
|
||||
url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
|
||||
@ -355,6 +363,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
fullName = "Independent JPEG Group License";
|
||||
};
|
||||
|
||||
imagemagick = spdx {
|
||||
fullName = "ImageMagick License";
|
||||
spdxId = "imagemagick";
|
||||
};
|
||||
|
||||
inria-compcert = {
|
||||
fullName = "INRIA Non-Commercial License Agreement for the CompCert verified compiler";
|
||||
url = "http://compcert.inria.fr/doc/LICENSE";
|
||||
@ -382,6 +395,18 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
fullName = "ISC License";
|
||||
};
|
||||
|
||||
# Proprietary binaries; free to redistribute without modification.
|
||||
issl = {
|
||||
fullName = "Intel Simplified Software License";
|
||||
url = https://software.intel.com/en-us/license/intel-simplified-software-license;
|
||||
free = false;
|
||||
};
|
||||
|
||||
jasper = spdx {
|
||||
spdxId = "JasPer-2.0";
|
||||
fullName = "JasPer License";
|
||||
};
|
||||
|
||||
lgpl2 = spdx {
|
||||
spdxId = "LGPL-2.0";
|
||||
fullName = "GNU Library General Public License v2 only";
|
||||
@ -480,6 +505,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
free = false;
|
||||
};
|
||||
|
||||
nasa13 = spdx {
|
||||
spdxId = "NASA-1.3";
|
||||
fullName = "NASA Open Source Agreement 1.3";
|
||||
free = false;
|
||||
};
|
||||
|
||||
ncsa = spdx {
|
||||
spdxId = "NCSA";
|
||||
fullName = "University of Illinois/NCSA Open Source License";
|
||||
@ -495,6 +526,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
fullName = "Non-Profit Open Software License 3.0";
|
||||
};
|
||||
|
||||
ocamlpro_nc = {
|
||||
fullName = "OCamlPro Non Commercial license version 1";
|
||||
url = "https://alt-ergo.ocamlpro.com/http/alt-ergo-2.2.0/OCamlPro-Non-Commercial-License.pdf";
|
||||
free = false;
|
||||
};
|
||||
|
||||
ofl = spdx {
|
||||
spdxId = "OFL-1.1";
|
||||
fullName = "SIL Open Font License 1.1";
|
||||
@ -546,6 +583,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
fullName = "Public Domain";
|
||||
};
|
||||
|
||||
purdueBsd = {
|
||||
fullName = " Purdue BSD-Style License"; # also know as lsof license
|
||||
url = https://enterprise.dejacode.com/licenses/public/purdue-bsd;
|
||||
};
|
||||
|
||||
qpl = spdx {
|
||||
spdxId = "QPL-1.0";
|
||||
fullName = "Q Public License 1.0";
|
||||
@ -561,6 +603,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
|
||||
fullName = "Ruby License";
|
||||
};
|
||||
|
||||
sendmail = spdx {
|
||||
spdxId = "Sendmail";
|
||||
fullName = "Sendmail License";
|
||||
};
|
||||
|
||||
sgi-b-20 = spdx {
|
||||
spdxId = "SGI-B-2.0";
|
||||
fullName = "SGI Free Software License B v2.0";
|
||||
|
191
lib/lists.nix
191
lib/lists.nix
@ -1,4 +1,5 @@
|
||||
# General list operations.
|
||||
|
||||
{ lib }:
|
||||
with lib.trivial;
|
||||
let
|
||||
@ -8,21 +9,23 @@ rec {
|
||||
|
||||
inherit (builtins) head tail length isList elemAt concatLists filter elem genList;
|
||||
|
||||
/* Create a list consisting of a single element. `singleton x' is
|
||||
sometimes more convenient with respect to indentation than `[x]'
|
||||
/* Create a list consisting of a single element. `singleton x` is
|
||||
sometimes more convenient with respect to indentation than `[x]`
|
||||
when x spans multiple lines.
|
||||
|
||||
Type: singleton :: a -> [a]
|
||||
|
||||
Example:
|
||||
singleton "foo"
|
||||
=> [ "foo" ]
|
||||
*/
|
||||
singleton = x: [x];
|
||||
|
||||
/* “right fold” a binary function `op' between successive elements of
|
||||
`list' with `nul' as the starting value, i.e.,
|
||||
`foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'.
|
||||
Type:
|
||||
foldr :: (a -> b -> b) -> b -> [a] -> b
|
||||
/* “right fold” a binary function `op` between successive elements of
|
||||
`list` with `nul' as the starting value, i.e.,
|
||||
`foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))`.
|
||||
|
||||
Type: foldr :: (a -> b -> b) -> b -> [a] -> b
|
||||
|
||||
Example:
|
||||
concat = foldr (a: b: a + b) "z"
|
||||
@ -42,16 +45,15 @@ rec {
|
||||
else op (elemAt list n) (fold' (n + 1));
|
||||
in fold' 0;
|
||||
|
||||
/* `fold' is an alias of `foldr' for historic reasons */
|
||||
/* `fold` is an alias of `foldr` for historic reasons */
|
||||
# FIXME(Profpatsch): deprecate?
|
||||
fold = foldr;
|
||||
|
||||
|
||||
/* “left fold”, like `foldr', but from the left:
|
||||
/* “left fold”, like `foldr`, but from the left:
|
||||
`foldl op nul [x_1 x_2 ... x_n] == op (... (op (op nul x_1) x_2) ... x_n)`.
|
||||
|
||||
Type:
|
||||
foldl :: (b -> a -> b) -> b -> [a] -> b
|
||||
Type: foldl :: (b -> a -> b) -> b -> [a] -> b
|
||||
|
||||
Example:
|
||||
lconcat = foldl (a: b: a + b) "z"
|
||||
@ -70,16 +72,20 @@ rec {
|
||||
else op (foldl' (n - 1)) (elemAt list n);
|
||||
in foldl' (length list - 1);
|
||||
|
||||
/* Strict version of `foldl'.
|
||||
/* Strict version of `foldl`.
|
||||
|
||||
The difference is that evaluation is forced upon access. Usually used
|
||||
with small whole results (in contract with lazily-generated list or large
|
||||
lists where only a part is consumed.)
|
||||
|
||||
Type: foldl' :: (b -> a -> b) -> b -> [a] -> b
|
||||
*/
|
||||
foldl' = builtins.foldl' or foldl;
|
||||
|
||||
/* Map with index starting from 0
|
||||
|
||||
Type: imap0 :: (int -> a -> b) -> [a] -> [b]
|
||||
|
||||
Example:
|
||||
imap0 (i: v: "${v}-${toString i}") ["a" "b"]
|
||||
=> [ "a-0" "b-1" ]
|
||||
@ -88,6 +94,8 @@ rec {
|
||||
|
||||
/* Map with index starting from 1
|
||||
|
||||
Type: imap1 :: (int -> a -> b) -> [a] -> [b]
|
||||
|
||||
Example:
|
||||
imap1 (i: v: "${v}-${toString i}") ["a" "b"]
|
||||
=> [ "a-1" "b-2" ]
|
||||
@ -96,6 +104,8 @@ rec {
|
||||
|
||||
/* Map and concatenate the result.
|
||||
|
||||
Type: concatMap :: (a -> [b]) -> [a] -> [b]
|
||||
|
||||
Example:
|
||||
concatMap (x: [x] ++ ["z"]) ["a" "b"]
|
||||
=> [ "a" "z" "b" "z" ]
|
||||
@ -118,15 +128,21 @@ rec {
|
||||
|
||||
/* Remove elements equal to 'e' from a list. Useful for buildInputs.
|
||||
|
||||
Type: remove :: a -> [a] -> [a]
|
||||
|
||||
Example:
|
||||
remove 3 [ 1 3 4 3 ]
|
||||
=> [ 1 4 ]
|
||||
*/
|
||||
remove = e: filter (x: x != e);
|
||||
remove =
|
||||
# Element to remove from the list
|
||||
e: filter (x: x != e);
|
||||
|
||||
/* Find the sole element in the list matching the specified
|
||||
predicate, returns `default' if no such element exists, or
|
||||
`multiple' if there are multiple matching elements.
|
||||
predicate, returns `default` if no such element exists, or
|
||||
`multiple` if there are multiple matching elements.
|
||||
|
||||
Type: findSingle :: (a -> bool) -> a -> a -> [a] -> a
|
||||
|
||||
Example:
|
||||
findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ]
|
||||
@ -136,14 +152,24 @@ rec {
|
||||
findSingle (x: x == 3) "none" "multiple" [ 1 9 ]
|
||||
=> "none"
|
||||
*/
|
||||
findSingle = pred: default: multiple: list:
|
||||
findSingle =
|
||||
# Predicate
|
||||
pred:
|
||||
# Default value to return if element was not found.
|
||||
default:
|
||||
# Default value to return if more than one element was found
|
||||
multiple:
|
||||
# Input list
|
||||
list:
|
||||
let found = filter pred list; len = length found;
|
||||
in if len == 0 then default
|
||||
else if len != 1 then multiple
|
||||
else head found;
|
||||
|
||||
/* Find the first element in the list matching the specified
|
||||
predicate or returns `default' if no such element exists.
|
||||
predicate or return `default` if no such element exists.
|
||||
|
||||
Type: findFirst :: (a -> bool) -> a -> [a] -> a
|
||||
|
||||
Example:
|
||||
findFirst (x: x > 3) 7 [ 1 6 4 ]
|
||||
@ -151,12 +177,20 @@ rec {
|
||||
findFirst (x: x > 9) 7 [ 1 6 4 ]
|
||||
=> 7
|
||||
*/
|
||||
findFirst = pred: default: list:
|
||||
findFirst =
|
||||
# Predicate
|
||||
pred:
|
||||
# Default value to return
|
||||
default:
|
||||
# Input list
|
||||
list:
|
||||
let found = filter pred list;
|
||||
in if found == [] then default else head found;
|
||||
|
||||
/* Return true iff function `pred' returns true for at least element
|
||||
of `list'.
|
||||
/* Return true if function `pred` returns true for at least one
|
||||
element of `list`.
|
||||
|
||||
Type: any :: (a -> bool) -> [a] -> bool
|
||||
|
||||
Example:
|
||||
any isString [ 1 "a" { } ]
|
||||
@ -166,8 +200,10 @@ rec {
|
||||
*/
|
||||
any = builtins.any or (pred: foldr (x: y: if pred x then true else y) false);
|
||||
|
||||
/* Return true iff function `pred' returns true for all elements of
|
||||
`list'.
|
||||
/* Return true if function `pred` returns true for all elements of
|
||||
`list`.
|
||||
|
||||
Type: all :: (a -> bool) -> [a] -> bool
|
||||
|
||||
Example:
|
||||
all (x: x < 3) [ 1 2 ]
|
||||
@ -177,19 +213,25 @@ rec {
|
||||
*/
|
||||
all = builtins.all or (pred: foldr (x: y: if pred x then y else false) true);
|
||||
|
||||
/* Count how many times function `pred' returns true for the elements
|
||||
of `list'.
|
||||
/* Count how many elements of `list` match the supplied predicate
|
||||
function.
|
||||
|
||||
Type: count :: (a -> bool) -> [a] -> int
|
||||
|
||||
Example:
|
||||
count (x: x == 3) [ 3 2 3 4 6 ]
|
||||
=> 2
|
||||
*/
|
||||
count = pred: foldl' (c: x: if pred x then c + 1 else c) 0;
|
||||
count =
|
||||
# Predicate
|
||||
pred: foldl' (c: x: if pred x then c + 1 else c) 0;
|
||||
|
||||
/* Return a singleton list or an empty list, depending on a boolean
|
||||
value. Useful when building lists with optional elements
|
||||
(e.g. `++ optional (system == "i686-linux") flashplayer').
|
||||
|
||||
Type: optional :: bool -> a -> [a]
|
||||
|
||||
Example:
|
||||
optional true "foo"
|
||||
=> [ "foo" ]
|
||||
@ -200,13 +242,19 @@ rec {
|
||||
|
||||
/* Return a list or an empty list, depending on a boolean value.
|
||||
|
||||
Type: optionals :: bool -> [a] -> [a]
|
||||
|
||||
Example:
|
||||
optionals true [ 2 3 ]
|
||||
=> [ 2 3 ]
|
||||
optionals false [ 2 3 ]
|
||||
=> [ ]
|
||||
*/
|
||||
optionals = cond: elems: if cond then elems else [];
|
||||
optionals =
|
||||
# Condition
|
||||
cond:
|
||||
# List to return if condition is true
|
||||
elems: if cond then elems else [];
|
||||
|
||||
|
||||
/* If argument is a list, return it; else, wrap it in a singleton
|
||||
@ -223,20 +271,28 @@ rec {
|
||||
|
||||
/* Return a list of integers from `first' up to and including `last'.
|
||||
|
||||
Type: range :: int -> int -> [int]
|
||||
|
||||
Example:
|
||||
range 2 4
|
||||
=> [ 2 3 4 ]
|
||||
range 3 2
|
||||
=> [ ]
|
||||
*/
|
||||
range = first: last:
|
||||
range =
|
||||
# First integer in the range
|
||||
first:
|
||||
# Last integer in the range
|
||||
last:
|
||||
if first > last then
|
||||
[]
|
||||
else
|
||||
genList (n: first + n) (last - first + 1);
|
||||
|
||||
/* Splits the elements of a list in two lists, `right' and
|
||||
`wrong', depending on the evaluation of a predicate.
|
||||
/* Splits the elements of a list in two lists, `right` and
|
||||
`wrong`, depending on the evaluation of a predicate.
|
||||
|
||||
Type: (a -> bool) -> [a] -> { right :: [a], wrong :: [a] }
|
||||
|
||||
Example:
|
||||
partition (x: x > 2) [ 5 1 2 3 4 ]
|
||||
@ -252,7 +308,7 @@ rec {
|
||||
/* Splits the elements of a list into many lists, using the return value of a predicate.
|
||||
Predicate should return a string which becomes keys of attrset `groupBy' returns.
|
||||
|
||||
`groupBy'' allows to customise the combining function and initial value
|
||||
`groupBy'` allows to customise the combining function and initial value
|
||||
|
||||
Example:
|
||||
groupBy (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
|
||||
@ -268,10 +324,6 @@ rec {
|
||||
xfce = [ { name = "xfce"; script = "xfce4-session &"; } ];
|
||||
}
|
||||
|
||||
|
||||
groupBy' allows to customise the combining function and initial value
|
||||
|
||||
Example:
|
||||
groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
|
||||
=> { true = 12; false = 3; }
|
||||
*/
|
||||
@ -289,17 +341,27 @@ rec {
|
||||
the merging stops at the shortest. How both lists are merged is defined
|
||||
by the first argument.
|
||||
|
||||
Type: zipListsWith :: (a -> b -> c) -> [a] -> [b] -> [c]
|
||||
|
||||
Example:
|
||||
zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"]
|
||||
=> ["he" "lo"]
|
||||
*/
|
||||
zipListsWith = f: fst: snd:
|
||||
zipListsWith =
|
||||
# Function to zip elements of both lists
|
||||
f:
|
||||
# First list
|
||||
fst:
|
||||
# Second list
|
||||
snd:
|
||||
genList
|
||||
(n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd));
|
||||
|
||||
/* Merges two lists of the same size together. If the sizes aren't the same
|
||||
the merging stops at the shortest.
|
||||
|
||||
Type: zipLists :: [a] -> [b] -> [{ fst :: a, snd :: b}]
|
||||
|
||||
Example:
|
||||
zipLists [ 1 2 ] [ "a" "b" ]
|
||||
=> [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ]
|
||||
@ -308,6 +370,8 @@ rec {
|
||||
|
||||
/* Reverse the order of the elements of a list.
|
||||
|
||||
Type: reverseList :: [a] -> [a]
|
||||
|
||||
Example:
|
||||
|
||||
reverseList [ "b" "o" "j" ]
|
||||
@ -321,8 +385,7 @@ rec {
|
||||
`before a b == true` means that `b` depends on `a` (there's an
|
||||
edge from `b` to `a`).
|
||||
|
||||
Examples:
|
||||
|
||||
Example:
|
||||
listDfs true hasPrefix [ "/home/user" "other" "/" "/home" ]
|
||||
== { minimal = "/"; # minimal element
|
||||
visited = [ "/home/user" ]; # seen elements (in reverse order)
|
||||
@ -336,7 +399,6 @@ rec {
|
||||
rest = [ "/home" "other" ]; # everything else
|
||||
|
||||
*/
|
||||
|
||||
listDfs = stopOnCycles: before: list:
|
||||
let
|
||||
dfs' = us: visited: rest:
|
||||
@ -361,7 +423,7 @@ rec {
|
||||
`before a b == true` means that `b` should be after `a`
|
||||
in the result.
|
||||
|
||||
Examples:
|
||||
Example:
|
||||
|
||||
toposort hasPrefix [ "/home/user" "other" "/" "/home" ]
|
||||
== { result = [ "/" "/home" "/home/user" "other" ]; }
|
||||
@ -376,7 +438,6 @@ rec {
|
||||
toposort (a: b: a < b) [ 3 2 1 ] == { result = [ 1 2 3 ]; }
|
||||
|
||||
*/
|
||||
|
||||
toposort = before: list:
|
||||
let
|
||||
dfsthis = listDfs true before list;
|
||||
@ -467,26 +528,38 @@ rec {
|
||||
|
||||
/* Return the first (at most) N elements of a list.
|
||||
|
||||
Type: take :: int -> [a] -> [a]
|
||||
|
||||
Example:
|
||||
take 2 [ "a" "b" "c" "d" ]
|
||||
=> [ "a" "b" ]
|
||||
take 2 [ ]
|
||||
=> [ ]
|
||||
*/
|
||||
take = count: sublist 0 count;
|
||||
take =
|
||||
# Number of elements to take
|
||||
count: sublist 0 count;
|
||||
|
||||
/* Remove the first (at most) N elements of a list.
|
||||
|
||||
Type: drop :: int -> [a] -> [a]
|
||||
|
||||
Example:
|
||||
drop 2 [ "a" "b" "c" "d" ]
|
||||
=> [ "c" "d" ]
|
||||
drop 2 [ ]
|
||||
=> [ ]
|
||||
*/
|
||||
drop = count: list: sublist count (length list) list;
|
||||
drop =
|
||||
# Number of elements to drop
|
||||
count:
|
||||
# Input list
|
||||
list: sublist count (length list) list;
|
||||
|
||||
/* Return a list consisting of at most ‘count’ elements of ‘list’,
|
||||
starting at index ‘start’.
|
||||
/* Return a list consisting of at most `count` elements of `list`,
|
||||
starting at index `start`.
|
||||
|
||||
Type: sublist :: int -> int -> [a] -> [a]
|
||||
|
||||
Example:
|
||||
sublist 1 3 [ "a" "b" "c" "d" "e" ]
|
||||
@ -494,7 +567,13 @@ rec {
|
||||
sublist 1 3 [ ]
|
||||
=> [ ]
|
||||
*/
|
||||
sublist = start: count: list:
|
||||
sublist =
|
||||
# Index at which to start the sublist
|
||||
start:
|
||||
# Number of elements to take
|
||||
count:
|
||||
# Input list
|
||||
list:
|
||||
let len = length list; in
|
||||
genList
|
||||
(n: elemAt list (n + start))
|
||||
@ -504,23 +583,34 @@ rec {
|
||||
|
||||
/* Return the last element of a list.
|
||||
|
||||
This function throws an error if the list is empty.
|
||||
|
||||
Type: last :: [a] -> a
|
||||
|
||||
Example:
|
||||
last [ 1 2 3 ]
|
||||
=> 3
|
||||
*/
|
||||
last = list:
|
||||
assert list != []; elemAt list (length list - 1);
|
||||
assert lib.assertMsg (list != []) "lists.last: list must not be empty!";
|
||||
elemAt list (length list - 1);
|
||||
|
||||
/* Return all elements but the last
|
||||
/* Return all elements but the last.
|
||||
|
||||
This function throws an error if the list is empty.
|
||||
|
||||
Type: init :: [a] -> [a]
|
||||
|
||||
Example:
|
||||
init [ 1 2 3 ]
|
||||
=> [ 1 2 ]
|
||||
*/
|
||||
init = list: assert list != []; take (length list - 1) list;
|
||||
init = list:
|
||||
assert lib.assertMsg (list != []) "lists.init: list must not be empty!";
|
||||
take (length list - 1) list;
|
||||
|
||||
|
||||
/* return the image of the cross product of some lists by a function
|
||||
/* Return the image of the cross product of some lists by a function.
|
||||
|
||||
Example:
|
||||
crossLists (x:y: "${toString x}${toString y}") [[1 2] [3 4]]
|
||||
@ -531,8 +621,9 @@ rec {
|
||||
|
||||
/* Remove duplicate elements from the list. O(n^2) complexity.
|
||||
|
||||
Example:
|
||||
Type: unique :: [a] -> [a]
|
||||
|
||||
Example:
|
||||
unique [ 3 2 3 4 ]
|
||||
=> [ 3 2 4 ]
|
||||
*/
|
||||
|
120
lib/options.nix
120
lib/options.nix
@ -8,33 +8,72 @@ with lib.strings;
|
||||
|
||||
rec {
|
||||
|
||||
/* Returns true when the given argument is an option
|
||||
|
||||
Type: isOption :: a -> bool
|
||||
|
||||
Example:
|
||||
isOption 1 // => false
|
||||
isOption (mkOption {}) // => true
|
||||
*/
|
||||
isOption = lib.isType "option";
|
||||
|
||||
/* Creates an Option attribute set. mkOption accepts an attribute set with the following keys:
|
||||
|
||||
All keys default to `null` when not given.
|
||||
|
||||
Example:
|
||||
mkOption { } // => { _type = "option"; }
|
||||
mkOption { defaultText = "foo"; } // => { _type = "option"; defaultText = "foo"; }
|
||||
*/
|
||||
mkOption =
|
||||
{ default ? null # Default value used when no definition is given in the configuration.
|
||||
, defaultText ? null # Textual representation of the default, for in the manual.
|
||||
, example ? null # Example value used in the manual.
|
||||
, description ? null # String describing the option.
|
||||
, relatedPackages ? null # Related packages used in the manual (see `genRelatedPackages` in ../nixos/doc/manual/default.nix).
|
||||
, type ? null # Option type, providing type-checking and value merging.
|
||||
, apply ? null # Function that converts the option value to something else.
|
||||
, internal ? null # Whether the option is for NixOS developers only.
|
||||
, visible ? null # Whether the option shows up in the manual.
|
||||
, readOnly ? null # Whether the option can be set only once
|
||||
, options ? null # Obsolete, used by types.optionSet.
|
||||
{
|
||||
# Default value used when no definition is given in the configuration.
|
||||
default ? null,
|
||||
# Textual representation of the default, for the manual.
|
||||
defaultText ? null,
|
||||
# Example value used in the manual.
|
||||
example ? null,
|
||||
# String describing the option.
|
||||
description ? null,
|
||||
# Related packages used in the manual (see `genRelatedPackages` in ../nixos/doc/manual/default.nix).
|
||||
relatedPackages ? null,
|
||||
# Option type, providing type-checking and value merging.
|
||||
type ? null,
|
||||
# Function that converts the option value to something else.
|
||||
apply ? null,
|
||||
# Whether the option is for NixOS developers only.
|
||||
internal ? null,
|
||||
# Whether the option shows up in the manual.
|
||||
visible ? null,
|
||||
# Whether the option can be set only once
|
||||
readOnly ? null,
|
||||
# Obsolete, used by types.optionSet.
|
||||
options ? null
|
||||
} @ attrs:
|
||||
attrs // { _type = "option"; };
|
||||
|
||||
mkEnableOption = name: mkOption {
|
||||
/* Creates an Option attribute set for a boolean value option i.e an
|
||||
option to be toggled on or off:
|
||||
|
||||
Example:
|
||||
mkEnableOption "foo"
|
||||
=> { _type = "option"; default = false; description = "Whether to enable foo."; example = true; type = { ... }; }
|
||||
*/
|
||||
mkEnableOption =
|
||||
# Name for the created option
|
||||
name: mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
description = "Whether to enable ${name}.";
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
# This option accept anything, but it does not produce any result. This
|
||||
# is useful for sharing a module across different module sets without
|
||||
# having to implement similar features as long as the value of the options
|
||||
# are not expected.
|
||||
/* This option accepts anything, but it does not produce any result.
|
||||
|
||||
This is useful for sharing a module across different module sets
|
||||
without having to implement similar features as long as the
|
||||
values of the options are not accessed. */
|
||||
mkSinkUndeclaredOptions = attrs: mkOption ({
|
||||
internal = true;
|
||||
visible = false;
|
||||
@ -74,7 +113,24 @@ rec {
|
||||
else
|
||||
val) (head defs).value defs;
|
||||
|
||||
/* Extracts values of all "value" keys of the given list.
|
||||
|
||||
Type: getValues :: [ { value :: a } ] -> [a]
|
||||
|
||||
Example:
|
||||
getValues [ { value = 1; } { value = 2; } ] // => [ 1 2 ]
|
||||
getValues [ ] // => [ ]
|
||||
*/
|
||||
getValues = map (x: x.value);
|
||||
|
||||
/* Extracts values of all "file" keys of the given list
|
||||
|
||||
Type: getFiles :: [ { file :: a } ] -> [a]
|
||||
|
||||
Example:
|
||||
getFiles [ { file = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ]
|
||||
getFiles [ ] // => [ ]
|
||||
*/
|
||||
getFiles = map (x: x.file);
|
||||
|
||||
# Generate documentation template from the list of option declaration like
|
||||
@ -107,10 +163,13 @@ rec {
|
||||
|
||||
|
||||
/* This function recursively removes all derivation attributes from
|
||||
`x' except for the `name' attribute. This is to make the
|
||||
generation of `options.xml' much more efficient: the XML
|
||||
representation of derivations is very large (on the order of
|
||||
megabytes) and is not actually used by the manual generator. */
|
||||
`x` except for the `name` attribute.
|
||||
|
||||
This is to make the generation of `options.xml` much more
|
||||
efficient: the XML representation of derivations is very large
|
||||
(on the order of megabytes) and is not actually used by the
|
||||
manual generator.
|
||||
*/
|
||||
scrubOptionValue = x:
|
||||
if isDerivation x then
|
||||
{ type = "derivation"; drvPath = x.name; outPath = x.name; name = x.name; }
|
||||
@ -119,20 +178,21 @@ rec {
|
||||
else x;
|
||||
|
||||
|
||||
/* For use in the ‘example’ option attribute. It causes the given
|
||||
text to be included verbatim in documentation. This is necessary
|
||||
for example values that are not simple values, e.g.,
|
||||
functions. */
|
||||
/* For use in the `example` option attribute. It causes the given
|
||||
text to be included verbatim in documentation. This is necessary
|
||||
for example values that are not simple values, e.g., functions.
|
||||
*/
|
||||
literalExample = text: { _type = "literalExample"; inherit text; };
|
||||
|
||||
# Helper functions.
|
||||
|
||||
/* Helper functions. */
|
||||
/* Convert an option, described as a list of the option parts in to a
|
||||
safe, human readable version.
|
||||
|
||||
# Convert an option, described as a list of the option parts in to a
|
||||
# safe, human readable version. ie:
|
||||
#
|
||||
# (showOption ["foo" "bar" "baz"]) == "foo.bar.baz"
|
||||
# (showOption ["foo" "bar.baz" "tux"]) == "foo.\"bar.baz\".tux"
|
||||
Example:
|
||||
(showOption ["foo" "bar" "baz"]) == "foo.bar.baz"
|
||||
(showOption ["foo" "bar.baz" "tux"]) == "foo.\"bar.baz\".tux"
|
||||
*/
|
||||
showOption = parts: let
|
||||
escapeOptionPart = part:
|
||||
let
|
||||
|
@ -26,6 +26,10 @@ rec {
|
||||
(type == "symlink" && lib.hasPrefix "result" baseName)
|
||||
);
|
||||
|
||||
# Filters a source tree removing version control files and directories using cleanSourceWith
|
||||
#
|
||||
# Example:
|
||||
# cleanSource ./.
|
||||
cleanSource = src: cleanSourceWith { filter = cleanSourceFilter; inherit src; };
|
||||
|
||||
# Like `builtins.filterSource`, except it will compose with itself,
|
||||
@ -69,7 +73,7 @@ rec {
|
||||
# Get the commit id of a git repo
|
||||
# Example: commitIdFromGitRepo <nixpkgs/.git>
|
||||
commitIdFromGitRepo =
|
||||
let readCommitFromFile = path: file:
|
||||
let readCommitFromFile = file: path:
|
||||
with builtins;
|
||||
let fileName = toString path + "/" + file;
|
||||
packedRefsName = toString path + "/packed-refs";
|
||||
@ -81,7 +85,7 @@ rec {
|
||||
matchRef = match "^ref: (.*)$" fileContent;
|
||||
in if isNull matchRef
|
||||
then fileContent
|
||||
else readCommitFromFile path (lib.head matchRef)
|
||||
else readCommitFromFile (lib.head matchRef) path
|
||||
# Sometimes, the file isn't there at all and has been packed away in the
|
||||
# packed-refs file, so we have to grep through it:
|
||||
else if lib.pathExists packedRefsName
|
||||
@ -92,7 +96,7 @@ rec {
|
||||
then throw ("Could not find " + file + " in " + packedRefsName)
|
||||
else lib.head matchRef
|
||||
else throw ("Not a .git directory: " + path);
|
||||
in lib.flip readCommitFromFile "HEAD";
|
||||
in readCommitFromFile "HEAD";
|
||||
|
||||
pathHasContext = builtins.hasContext or (lib.hasPrefix builtins.storeDir);
|
||||
|
||||
|
243
lib/strings.nix
243
lib/strings.nix
@ -12,6 +12,8 @@ rec {
|
||||
|
||||
/* Concatenate a list of strings.
|
||||
|
||||
Type: concatStrings :: [string] -> string
|
||||
|
||||
Example:
|
||||
concatStrings ["foo" "bar"]
|
||||
=> "foobar"
|
||||
@ -20,15 +22,19 @@ rec {
|
||||
|
||||
/* Map a function over a list and concatenate the resulting strings.
|
||||
|
||||
Type: concatMapStrings :: (a -> string) -> [a] -> string
|
||||
|
||||
Example:
|
||||
concatMapStrings (x: "a" + x) ["foo" "bar"]
|
||||
=> "afooabar"
|
||||
*/
|
||||
concatMapStrings = f: list: concatStrings (map f list);
|
||||
|
||||
/* Like `concatMapStrings' except that the f functions also gets the
|
||||
/* Like `concatMapStrings` except that the f functions also gets the
|
||||
position as a parameter.
|
||||
|
||||
Type: concatImapStrings :: (int -> a -> string) -> [a] -> string
|
||||
|
||||
Example:
|
||||
concatImapStrings (pos: x: "${toString pos}-${x}") ["foo" "bar"]
|
||||
=> "1-foo2-bar"
|
||||
@ -37,17 +43,25 @@ rec {
|
||||
|
||||
/* Place an element between each element of a list
|
||||
|
||||
Type: intersperse :: a -> [a] -> [a]
|
||||
|
||||
Example:
|
||||
intersperse "/" ["usr" "local" "bin"]
|
||||
=> ["usr" "/" "local" "/" "bin"].
|
||||
*/
|
||||
intersperse = separator: list:
|
||||
intersperse =
|
||||
# Separator to add between elements
|
||||
separator:
|
||||
# Input list
|
||||
list:
|
||||
if list == [] || length list == 1
|
||||
then list
|
||||
else tail (lib.concatMap (x: [separator x]) list);
|
||||
|
||||
/* Concatenate a list of strings with a separator between each element
|
||||
|
||||
Type: concatStringsSep :: string -> [string] -> string
|
||||
|
||||
Example:
|
||||
concatStringsSep "/" ["usr" "local" "bin"]
|
||||
=> "usr/local/bin"
|
||||
@ -55,43 +69,77 @@ rec {
|
||||
concatStringsSep = builtins.concatStringsSep or (separator: list:
|
||||
concatStrings (intersperse separator list));
|
||||
|
||||
/* First maps over the list and then concatenates it.
|
||||
/* Maps a function over a list of strings and then concatenates the
|
||||
result with the specified separator interspersed between
|
||||
elements.
|
||||
|
||||
Type: concatMapStringsSep :: string -> (string -> string) -> [string] -> string
|
||||
|
||||
Example:
|
||||
concatMapStringsSep "-" (x: toUpper x) ["foo" "bar" "baz"]
|
||||
=> "FOO-BAR-BAZ"
|
||||
*/
|
||||
concatMapStringsSep = sep: f: list: concatStringsSep sep (map f list);
|
||||
concatMapStringsSep =
|
||||
# Separator to add between elements
|
||||
sep:
|
||||
# Function to map over the list
|
||||
f:
|
||||
# List of input strings
|
||||
list: concatStringsSep sep (map f list);
|
||||
|
||||
/* First imaps over the list and then concatenates it.
|
||||
/* Same as `concatMapStringsSep`, but the mapping function
|
||||
additionally receives the position of its argument.
|
||||
|
||||
Type: concatMapStringsSep :: string -> (int -> string -> string) -> [string] -> string
|
||||
|
||||
Example:
|
||||
|
||||
concatImapStringsSep "-" (pos: x: toString (x / pos)) [ 6 6 6 ]
|
||||
=> "6-3-2"
|
||||
*/
|
||||
concatImapStringsSep = sep: f: list: concatStringsSep sep (lib.imap1 f list);
|
||||
concatImapStringsSep =
|
||||
# Separator to add between elements
|
||||
sep:
|
||||
# Function that receives elements and their positions
|
||||
f:
|
||||
# List of input strings
|
||||
list: concatStringsSep sep (lib.imap1 f list);
|
||||
|
||||
/* Construct a Unix-style search path consisting of each `subDir"
|
||||
directory of the given list of packages.
|
||||
/* Construct a Unix-style, colon-separated search path consisting of
|
||||
the given `subDir` appended to each of the given paths.
|
||||
|
||||
Type: makeSearchPath :: string -> [string] -> string
|
||||
|
||||
Example:
|
||||
makeSearchPath "bin" ["/root" "/usr" "/usr/local"]
|
||||
=> "/root/bin:/usr/bin:/usr/local/bin"
|
||||
makeSearchPath "bin" ["/"]
|
||||
=> "//bin"
|
||||
makeSearchPath "bin" [""]
|
||||
=> "/bin"
|
||||
*/
|
||||
makeSearchPath = subDir: packages:
|
||||
concatStringsSep ":" (map (path: path + "/" + subDir) (builtins.filter (x: x != null) packages));
|
||||
makeSearchPath =
|
||||
# Directory name to append
|
||||
subDir:
|
||||
# List of base paths
|
||||
paths:
|
||||
concatStringsSep ":" (map (path: path + "/" + subDir) (builtins.filter (x: x != null) paths));
|
||||
|
||||
/* Construct a Unix-style search path, using given package output.
|
||||
If no output is found, fallback to `.out` and then to the default.
|
||||
/* Construct a Unix-style search path by appending the given
|
||||
`subDir` to the specified `output` of each of the packages. If no
|
||||
output by the given name is found, fallback to `.out` and then to
|
||||
the default.
|
||||
|
||||
Type: string -> string -> [package] -> string
|
||||
|
||||
Example:
|
||||
makeSearchPathOutput "dev" "bin" [ pkgs.openssl pkgs.zlib ]
|
||||
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev/bin:/nix/store/wwh7mhwh269sfjkm6k5665b5kgp7jrk2-zlib-1.2.8/bin"
|
||||
*/
|
||||
makeSearchPathOutput = output: subDir: pkgs: makeSearchPath subDir (map (lib.getOutput output) pkgs);
|
||||
makeSearchPathOutput =
|
||||
# Package output to use
|
||||
output:
|
||||
# Directory name to append
|
||||
subDir:
|
||||
# List of packages
|
||||
pkgs: makeSearchPath subDir (map (lib.getOutput output) pkgs);
|
||||
|
||||
/* Construct a library search path (such as RPATH) containing the
|
||||
libraries for a set of packages
|
||||
@ -117,13 +165,12 @@ rec {
|
||||
|
||||
/* Construct a perl search path (such as $PERL5LIB)
|
||||
|
||||
FIXME(zimbatm): this should be moved in perl-specific code
|
||||
|
||||
Example:
|
||||
pkgs = import <nixpkgs> { }
|
||||
makePerlPath [ pkgs.perlPackages.libnet ]
|
||||
=> "/nix/store/n0m1fk9c960d8wlrs62sncnadygqqc6y-perl-Net-SMTP-1.25/lib/perl5/site_perl"
|
||||
*/
|
||||
# FIXME(zimbatm): this should be moved in perl-specific code
|
||||
makePerlPath = makeSearchPathOutput "lib" "lib/perl5/site_perl";
|
||||
|
||||
/* Construct a perl search path recursively including all dependencies (such as $PERL5LIB)
|
||||
@ -138,40 +185,77 @@ rec {
|
||||
/* Depending on the boolean `cond', return either the given string
|
||||
or the empty string. Useful to concatenate against a bigger string.
|
||||
|
||||
Type: optionalString :: bool -> string -> string
|
||||
|
||||
Example:
|
||||
optionalString true "some-string"
|
||||
=> "some-string"
|
||||
optionalString false "some-string"
|
||||
=> ""
|
||||
*/
|
||||
optionalString = cond: string: if cond then string else "";
|
||||
optionalString =
|
||||
# Condition
|
||||
cond:
|
||||
# String to return if condition is true
|
||||
string: if cond then string else "";
|
||||
|
||||
/* Determine whether a string has given prefix.
|
||||
|
||||
Type: hasPrefix :: string -> string -> bool
|
||||
|
||||
Example:
|
||||
hasPrefix "foo" "foobar"
|
||||
=> true
|
||||
hasPrefix "foo" "barfoo"
|
||||
=> false
|
||||
*/
|
||||
hasPrefix = pref: str:
|
||||
substring 0 (stringLength pref) str == pref;
|
||||
hasPrefix =
|
||||
# Prefix to check for
|
||||
pref:
|
||||
# Input string
|
||||
str: substring 0 (stringLength pref) str == pref;
|
||||
|
||||
/* Determine whether a string has given suffix.
|
||||
|
||||
Type: hasSuffix :: string -> string -> bool
|
||||
|
||||
Example:
|
||||
hasSuffix "foo" "foobar"
|
||||
=> false
|
||||
hasSuffix "foo" "barfoo"
|
||||
=> true
|
||||
*/
|
||||
hasSuffix = suffix: content:
|
||||
hasSuffix =
|
||||
# Suffix to check for
|
||||
suffix:
|
||||
# Input string
|
||||
content:
|
||||
let
|
||||
lenContent = stringLength content;
|
||||
lenSuffix = stringLength suffix;
|
||||
in lenContent >= lenSuffix &&
|
||||
substring (lenContent - lenSuffix) lenContent content == suffix;
|
||||
|
||||
/* Determine whether a string contains the given infix
|
||||
|
||||
Type: hasInfix :: string -> string -> bool
|
||||
|
||||
Example:
|
||||
hasInfix "bc" "abcd"
|
||||
=> true
|
||||
hasInfix "ab" "abcd"
|
||||
=> true
|
||||
hasInfix "cd" "abcd"
|
||||
=> true
|
||||
hasInfix "foo" "abcd"
|
||||
=> false
|
||||
*/
|
||||
hasInfix = infix: content:
|
||||
let
|
||||
drop = x: substring 1 (stringLength x) x;
|
||||
in hasPrefix infix content
|
||||
|| content != "" && hasInfix infix (drop content);
|
||||
|
||||
/* Convert a string to a list of characters (i.e. singleton strings).
|
||||
This allows you to, e.g., map a function over each character. However,
|
||||
note that this will likely be horribly inefficient; Nix is not a
|
||||
@ -180,6 +264,8 @@ rec {
|
||||
Also note that Nix treats strings as a list of bytes and thus doesn't
|
||||
handle unicode.
|
||||
|
||||
Type: stringtoCharacters :: string -> [string]
|
||||
|
||||
Example:
|
||||
stringToCharacters ""
|
||||
=> [ ]
|
||||
@ -194,18 +280,25 @@ rec {
|
||||
/* Manipulate a string character by character and replace them by
|
||||
strings before concatenating the results.
|
||||
|
||||
Type: stringAsChars :: (string -> string) -> string -> string
|
||||
|
||||
Example:
|
||||
stringAsChars (x: if x == "a" then "i" else x) "nax"
|
||||
=> "nix"
|
||||
*/
|
||||
stringAsChars = f: s:
|
||||
concatStrings (
|
||||
stringAsChars =
|
||||
# Function to map over each individual character
|
||||
f:
|
||||
# Input string
|
||||
s: concatStrings (
|
||||
map f (stringToCharacters s)
|
||||
);
|
||||
|
||||
/* Escape occurrence of the elements of ‘list’ in ‘string’ by
|
||||
/* Escape occurrence of the elements of `list` in `string` by
|
||||
prefixing it with a backslash.
|
||||
|
||||
Type: escape :: [string] -> string -> string
|
||||
|
||||
Example:
|
||||
escape ["(" ")"] "(foo)"
|
||||
=> "\\(foo\\)"
|
||||
@ -214,6 +307,8 @@ rec {
|
||||
|
||||
/* Quote string to be used safely within the Bourne shell.
|
||||
|
||||
Type: escapeShellArg :: string -> string
|
||||
|
||||
Example:
|
||||
escapeShellArg "esc'ape\nme"
|
||||
=> "'esc'\\''ape\nme'"
|
||||
@ -222,6 +317,8 @@ rec {
|
||||
|
||||
/* Quote all arguments to be safely passed to the Bourne shell.
|
||||
|
||||
Type: escapeShellArgs :: [string] -> string
|
||||
|
||||
Example:
|
||||
escapeShellArgs ["one" "two three" "four'five"]
|
||||
=> "'one' 'two three' 'four'\\''five'"
|
||||
@ -230,13 +327,15 @@ rec {
|
||||
|
||||
/* Turn a string into a Nix expression representing that string
|
||||
|
||||
Type: string -> string
|
||||
|
||||
Example:
|
||||
escapeNixString "hello\${}\n"
|
||||
=> "\"hello\\\${}\\n\""
|
||||
*/
|
||||
escapeNixString = s: escape ["$"] (builtins.toJSON s);
|
||||
|
||||
/* Obsolete - use replaceStrings instead. */
|
||||
# Obsolete - use replaceStrings instead.
|
||||
replaceChars = builtins.replaceStrings or (
|
||||
del: new: s:
|
||||
let
|
||||
@ -256,6 +355,8 @@ rec {
|
||||
|
||||
/* Converts an ASCII string to lower-case.
|
||||
|
||||
Type: toLower :: string -> string
|
||||
|
||||
Example:
|
||||
toLower "HOME"
|
||||
=> "home"
|
||||
@ -264,6 +365,8 @@ rec {
|
||||
|
||||
/* Converts an ASCII string to upper-case.
|
||||
|
||||
Type: toUpper :: string -> string
|
||||
|
||||
Example:
|
||||
toUpper "home"
|
||||
=> "HOME"
|
||||
@ -273,7 +376,7 @@ rec {
|
||||
/* Appends string context from another string. This is an implementation
|
||||
detail of Nix.
|
||||
|
||||
Strings in Nix carry an invisible `context' which is a list of strings
|
||||
Strings in Nix carry an invisible `context` which is a list of strings
|
||||
representing store paths. If the string is later used in a derivation
|
||||
attribute, the derivation will properly populate the inputDrvs and
|
||||
inputSrcs.
|
||||
@ -319,8 +422,9 @@ rec {
|
||||
in
|
||||
recurse 0 0;
|
||||
|
||||
/* Return the suffix of the second argument if the first argument matches
|
||||
its prefix.
|
||||
/* Return a string without the specified prefix, if the prefix matches.
|
||||
|
||||
Type: string -> string -> string
|
||||
|
||||
Example:
|
||||
removePrefix "foo." "foo.bar.baz"
|
||||
@ -328,18 +432,23 @@ rec {
|
||||
removePrefix "xxx" "foo.bar.baz"
|
||||
=> "foo.bar.baz"
|
||||
*/
|
||||
removePrefix = pre: s:
|
||||
removePrefix =
|
||||
# Prefix to remove if it matches
|
||||
prefix:
|
||||
# Input string
|
||||
str:
|
||||
let
|
||||
preLen = stringLength pre;
|
||||
sLen = stringLength s;
|
||||
preLen = stringLength prefix;
|
||||
sLen = stringLength str;
|
||||
in
|
||||
if hasPrefix pre s then
|
||||
substring preLen (sLen - preLen) s
|
||||
if hasPrefix prefix str then
|
||||
substring preLen (sLen - preLen) str
|
||||
else
|
||||
s;
|
||||
str;
|
||||
|
||||
/* Return the prefix of the second argument if the first argument matches
|
||||
its suffix.
|
||||
/* Return a string without the specified suffix, if the suffix matches.
|
||||
|
||||
Type: string -> string -> string
|
||||
|
||||
Example:
|
||||
removeSuffix "front" "homefront"
|
||||
@ -347,17 +456,21 @@ rec {
|
||||
removeSuffix "xxx" "homefront"
|
||||
=> "homefront"
|
||||
*/
|
||||
removeSuffix = suf: s:
|
||||
removeSuffix =
|
||||
# Suffix to remove if it matches
|
||||
suffix:
|
||||
# Input string
|
||||
str:
|
||||
let
|
||||
sufLen = stringLength suf;
|
||||
sLen = stringLength s;
|
||||
sufLen = stringLength suffix;
|
||||
sLen = stringLength str;
|
||||
in
|
||||
if sufLen <= sLen && suf == substring (sLen - sufLen) sufLen s then
|
||||
substring 0 (sLen - sufLen) s
|
||||
if sufLen <= sLen && suffix == substring (sLen - sufLen) sufLen str then
|
||||
substring 0 (sLen - sufLen) str
|
||||
else
|
||||
s;
|
||||
str;
|
||||
|
||||
/* Return true iff string v1 denotes a version older than v2.
|
||||
/* Return true if string v1 denotes a version older than v2.
|
||||
|
||||
Example:
|
||||
versionOlder "1.1" "1.2"
|
||||
@ -367,7 +480,7 @@ rec {
|
||||
*/
|
||||
versionOlder = v1: v2: builtins.compareVersions v2 v1 == 1;
|
||||
|
||||
/* Return true iff string v1 denotes a version equal to or newer than v2.
|
||||
/* Return true if string v1 denotes a version equal to or newer than v2.
|
||||
|
||||
Example:
|
||||
versionAtLeast "1.1" "1.0"
|
||||
@ -410,7 +523,7 @@ rec {
|
||||
components = splitString "/" url;
|
||||
filename = lib.last components;
|
||||
name = builtins.head (splitString sep filename);
|
||||
in assert name != filename; name;
|
||||
in assert name != filename; name;
|
||||
|
||||
/* Create an --{enable,disable}-<feat> string that can be passed to
|
||||
standard GNU Autoconf scripts.
|
||||
@ -459,6 +572,11 @@ rec {
|
||||
/* Create a fixed width string with additional prefix to match
|
||||
required width.
|
||||
|
||||
This function will fail if the input string is longer than the
|
||||
requested length.
|
||||
|
||||
Type: fixedWidthString :: int -> string -> string
|
||||
|
||||
Example:
|
||||
fixedWidthString 5 "0" (toString 15)
|
||||
=> "00015"
|
||||
@ -468,7 +586,10 @@ rec {
|
||||
strw = lib.stringLength str;
|
||||
reqWidth = width - (lib.stringLength filler);
|
||||
in
|
||||
assert strw <= width;
|
||||
assert lib.assertMsg (strw <= width)
|
||||
"fixedWidthString: requested string length (${
|
||||
toString width}) must not be shorter than actual length (${
|
||||
toString strw})";
|
||||
if strw == width then str else filler + fixedWidthString reqWidth filler str;
|
||||
|
||||
/* Format a number adding leading zeroes up to fixed width.
|
||||
@ -499,12 +620,16 @@ rec {
|
||||
=> false
|
||||
*/
|
||||
isStorePath = x:
|
||||
isCoercibleToString x
|
||||
&& builtins.substring 0 1 (toString x) == "/"
|
||||
&& dirOf (builtins.toPath x) == builtins.storeDir;
|
||||
if isCoercibleToString x then
|
||||
let str = toString x; in
|
||||
builtins.substring 0 1 str == "/"
|
||||
&& dirOf str == builtins.storeDir
|
||||
else
|
||||
false;
|
||||
|
||||
/* Convert string to int
|
||||
Obviously, it is a bit hacky to use fromJSON that way.
|
||||
/* Parse a string string as an int.
|
||||
|
||||
Type: string -> int
|
||||
|
||||
Example:
|
||||
toInt "1337"
|
||||
@ -514,17 +639,18 @@ rec {
|
||||
toInt "3.14"
|
||||
=> error: floating point JSON numbers are not supported
|
||||
*/
|
||||
# Obviously, it is a bit hacky to use fromJSON this way.
|
||||
toInt = str:
|
||||
let may_be_int = builtins.fromJSON str; in
|
||||
if builtins.isInt may_be_int
|
||||
then may_be_int
|
||||
else throw "Could not convert ${str} to int.";
|
||||
|
||||
/* Read a list of paths from `file', relative to the `rootPath'. Lines
|
||||
beginning with `#' are treated as comments and ignored. Whitespace
|
||||
is significant.
|
||||
/* Read a list of paths from `file`, relative to the `rootPath`.
|
||||
Lines beginning with `#` are treated as comments and ignored.
|
||||
Whitespace is significant.
|
||||
|
||||
NOTE: this function is not performant and should be avoided
|
||||
NOTE: This function is not performant and should be avoided.
|
||||
|
||||
Example:
|
||||
readPathsFromFile /prefix
|
||||
@ -537,16 +663,17 @@ rec {
|
||||
*/
|
||||
readPathsFromFile = rootPath: file:
|
||||
let
|
||||
root = toString rootPath;
|
||||
lines = lib.splitString "\n" (builtins.readFile file);
|
||||
removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
|
||||
relativePaths = removeComments lines;
|
||||
absolutePaths = builtins.map (path: builtins.toPath (root + "/" + path)) relativePaths;
|
||||
absolutePaths = builtins.map (path: rootPath + "/${path}") relativePaths;
|
||||
in
|
||||
absolutePaths;
|
||||
|
||||
/* Read the contents of a file removing the trailing \n
|
||||
|
||||
Type: fileContents :: path -> string
|
||||
|
||||
Example:
|
||||
$ echo "1.0" > ./version
|
||||
|
||||
|
@ -32,6 +32,7 @@ rec {
|
||||
else if final.isUClibc then "uclibc"
|
||||
else if final.isAndroid then "bionic"
|
||||
else if final.isLinux /* default */ then "glibc"
|
||||
else if final.isAvr then "avrlibc"
|
||||
# TODO(@Ericson2314) think more about other operating systems
|
||||
else "native/impure";
|
||||
extensions = {
|
||||
@ -46,6 +47,65 @@ rec {
|
||||
# Misc boolean options
|
||||
useAndroidPrebuilt = false;
|
||||
useiOSPrebuilt = false;
|
||||
|
||||
# Output from uname
|
||||
uname = {
|
||||
# uname -s
|
||||
system = {
|
||||
"linux" = "Linux";
|
||||
"windows" = "Windows";
|
||||
"darwin" = "Darwin";
|
||||
"netbsd" = "NetBSD";
|
||||
"freebsd" = "FreeBSD";
|
||||
"openbsd" = "OpenBSD";
|
||||
}.${final.parsed.kernel.name} or null;
|
||||
|
||||
# uname -p
|
||||
processor = final.parsed.cpu.name;
|
||||
|
||||
# uname -r
|
||||
release = null;
|
||||
};
|
||||
|
||||
qemuArch =
|
||||
if final.isArm then "arm"
|
||||
else if final.isx86_64 then "x86_64"
|
||||
else if final.isx86 then "i386"
|
||||
else {
|
||||
"powerpc" = "ppc";
|
||||
"powerpc64" = "ppc64";
|
||||
"powerpc64le" = "ppc64";
|
||||
"mips64" = "mips";
|
||||
"mipsel64" = "mipsel";
|
||||
}.${final.parsed.cpu.name} or final.parsed.cpu.name;
|
||||
|
||||
emulator = pkgs: let
|
||||
qemu-user = pkgs.qemu.override {
|
||||
smartcardSupport = false;
|
||||
spiceSupport = false;
|
||||
openGLSupport = false;
|
||||
virglSupport = false;
|
||||
vncSupport = false;
|
||||
gtkSupport = false;
|
||||
sdlSupport = false;
|
||||
pulseSupport = false;
|
||||
smbdSupport = false;
|
||||
seccompSupport = false;
|
||||
hostCpuTargets = ["${final.qemuArch}-linux-user"];
|
||||
};
|
||||
wine-name = "wine${toString final.parsed.cpu.bits}";
|
||||
wine = (pkgs.winePackagesFor wine-name).minimal;
|
||||
in
|
||||
if final.parsed.kernel.name == pkgs.stdenv.hostPlatform.parsed.kernel.name &&
|
||||
(final.parsed.cpu.name == pkgs.stdenv.hostPlatform.parsed.cpu.name ||
|
||||
(final.platform.isi686 && pkgs.stdenv.hostPlatform.isx86_64))
|
||||
then pkgs.runtimeShell
|
||||
else if final.isWindows
|
||||
then "${wine}/bin/${wine-name}"
|
||||
else if final.isLinux && pkgs.stdenv.hostPlatform.isLinux
|
||||
then "${qemu-user}/bin/qemu-${final.qemuArch}"
|
||||
else throw "Don't know how to run ${final.config} executables.";
|
||||
|
||||
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
||||
// args;
|
||||
in assert final.useAndroidPrebuilt -> final.isAndroid;
|
||||
|
@ -15,6 +15,8 @@ let
|
||||
|
||||
"x86_64-cygwin" "x86_64-darwin" "x86_64-freebsd" "x86_64-linux"
|
||||
"x86_64-netbsd" "x86_64-openbsd" "x86_64-solaris"
|
||||
|
||||
"x86_64-windows" "i686-windows"
|
||||
];
|
||||
|
||||
allParsed = map parse.mkSystemFromString all;
|
||||
@ -37,12 +39,13 @@ in rec {
|
||||
darwin = filterDoubles predicates.isDarwin;
|
||||
freebsd = filterDoubles predicates.isFreeBSD;
|
||||
# Should be better, but MinGW is unclear.
|
||||
gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; });
|
||||
gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabi; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabihf; });
|
||||
illumos = filterDoubles predicates.isSunOS;
|
||||
linux = filterDoubles predicates.isLinux;
|
||||
netbsd = filterDoubles predicates.isNetBSD;
|
||||
openbsd = filterDoubles predicates.isOpenBSD;
|
||||
unix = filterDoubles predicates.isUnix;
|
||||
windows = filterDoubles predicates.isWindows;
|
||||
|
||||
mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "powerpc64le-linux"];
|
||||
}
|
||||
|
@ -2,7 +2,14 @@
|
||||
# `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
|
||||
let
|
||||
platforms = import ./platforms.nix { inherit lib; };
|
||||
|
||||
riscv = bits: {
|
||||
config = "riscv${bits}-unknown-linux-gnu";
|
||||
platform = platforms.riscv-multiplatform bits;
|
||||
};
|
||||
in
|
||||
|
||||
rec {
|
||||
#
|
||||
@ -28,7 +35,7 @@ rec {
|
||||
};
|
||||
|
||||
armv7l-hf-multiplatform = rec {
|
||||
config = "armv7a-unknown-linux-gnueabihf";
|
||||
config = "armv7l-unknown-linux-gnueabihf";
|
||||
platform = platforms.armv7l-hf-multiplatform;
|
||||
};
|
||||
|
||||
@ -92,13 +99,56 @@ rec {
|
||||
musl64 = { config = "x86_64-unknown-linux-musl"; };
|
||||
musl32 = { config = "i686-unknown-linux-musl"; };
|
||||
|
||||
riscv = bits: {
|
||||
config = "riscv${bits}-unknown-linux-gnu";
|
||||
platform = platforms.riscv-multiplatform bits;
|
||||
};
|
||||
riscv64 = riscv "64";
|
||||
riscv32 = riscv "32";
|
||||
|
||||
avr = {
|
||||
config = "avr";
|
||||
};
|
||||
|
||||
arm-embedded = {
|
||||
config = "arm-none-eabi";
|
||||
libc = "newlib";
|
||||
};
|
||||
armhf-embedded = {
|
||||
config = "arm-none-eabihf";
|
||||
libc = "newlib";
|
||||
};
|
||||
|
||||
aarch64-embedded = {
|
||||
config = "aarch64-none-elf";
|
||||
libc = "newlib";
|
||||
};
|
||||
|
||||
aarch64be-embedded = {
|
||||
config = "aarch64_be-none-elf";
|
||||
libc = "newlib";
|
||||
};
|
||||
|
||||
ppc-embedded = {
|
||||
config = "powerpc-none-eabi";
|
||||
libc = "newlib";
|
||||
};
|
||||
|
||||
ppcle-embedded = {
|
||||
config = "powerpcle-none-eabi";
|
||||
libc = "newlib";
|
||||
};
|
||||
|
||||
alpha-embedded = {
|
||||
config = "alpha-elf";
|
||||
libc = "newlib";
|
||||
};
|
||||
|
||||
i686-embedded = {
|
||||
config = "i686-elf";
|
||||
libc = "newlib";
|
||||
};
|
||||
|
||||
x86_64-embedded = {
|
||||
config = "x86_64-elf";
|
||||
libc = "newlib";
|
||||
};
|
||||
|
||||
#
|
||||
# Darwin
|
||||
|
@ -19,6 +19,7 @@ rec {
|
||||
isRiscV = { cpu = { family = "riscv"; }; };
|
||||
isSparc = { cpu = { family = "sparc"; }; };
|
||||
isWasm = { cpu = { family = "wasm"; }; };
|
||||
isAvr = { cpu = { family = "avr"; }; };
|
||||
|
||||
is32bit = { cpu = { bits = 32; }; };
|
||||
is64bit = { cpu = { bits = 64; }; };
|
||||
|
@ -80,7 +80,11 @@ rec {
|
||||
armv8r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
|
||||
armv8m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
|
||||
aarch64 = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; };
|
||||
aarch64_be = { bits = 64; significantByte = bigEndian; family = "arm"; version = "8"; };
|
||||
|
||||
i386 = { bits = 32; significantByte = littleEndian; family = "x86"; };
|
||||
i486 = { bits = 32; significantByte = littleEndian; family = "x86"; };
|
||||
i586 = { bits = 32; significantByte = littleEndian; family = "x86"; };
|
||||
i686 = { bits = 32; significantByte = littleEndian; family = "x86"; };
|
||||
x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; };
|
||||
|
||||
@ -92,6 +96,7 @@ rec {
|
||||
powerpc = { bits = 32; significantByte = bigEndian; family = "power"; };
|
||||
powerpc64 = { bits = 64; significantByte = bigEndian; family = "power"; };
|
||||
powerpc64le = { bits = 64; significantByte = littleEndian; family = "power"; };
|
||||
powerpcle = { bits = 32; significantByte = littleEndian; family = "power"; };
|
||||
|
||||
riscv32 = { bits = 32; significantByte = littleEndian; family = "riscv"; };
|
||||
riscv64 = { bits = 64; significantByte = littleEndian; family = "riscv"; };
|
||||
@ -101,6 +106,10 @@ rec {
|
||||
|
||||
wasm32 = { bits = 32; significantByte = littleEndian; family = "wasm"; };
|
||||
wasm64 = { bits = 64; significantByte = littleEndian; family = "wasm"; };
|
||||
|
||||
alpha = { bits = 64; significantByte = littleEndian; family = "alpha"; };
|
||||
|
||||
avr = { bits = 8; family = "avr"; };
|
||||
};
|
||||
|
||||
################################################################################
|
||||
@ -117,6 +126,7 @@ rec {
|
||||
apple = {};
|
||||
pc = {};
|
||||
|
||||
none = {};
|
||||
unknown = {};
|
||||
};
|
||||
|
||||
@ -199,7 +209,15 @@ rec {
|
||||
abis = setTypes types.openAbi {
|
||||
cygnus = {};
|
||||
msvc = {};
|
||||
eabi = {};
|
||||
|
||||
# Note: eabi is specific to ARM and PowerPC.
|
||||
# On PowerPC, this corresponds to PPCEABI.
|
||||
# On ARM, this corresponds to ARMEABI.
|
||||
eabi = { float = "soft"; };
|
||||
eabihf = { float = "hard"; };
|
||||
|
||||
# Other architectures should use ELF in embedded situations.
|
||||
elf = {};
|
||||
|
||||
androideabi = {};
|
||||
android = {
|
||||
@ -255,9 +273,14 @@ rec {
|
||||
setType "system" components;
|
||||
|
||||
mkSkeletonFromList = l: {
|
||||
"1" = if elemAt l 0 == "avr"
|
||||
then { cpu = elemAt l 0; kernel = "none"; abi = "unknown"; }
|
||||
else throw "Target specification with 1 components is ambiguous";
|
||||
"2" = # We only do 2-part hacks for things Nix already supports
|
||||
if elemAt l 1 == "cygwin"
|
||||
then { cpu = elemAt l 0; kernel = "windows"; abi = "cygnus"; }
|
||||
else if (elemAt l 1) == "elf"
|
||||
then { cpu = elemAt l 0; vendor = "unknown"; kernel = "none"; abi = elemAt l 1; }
|
||||
else { cpu = elemAt l 0; kernel = elemAt l 1; };
|
||||
"3" = # Awkwards hacks, beware!
|
||||
if elemAt l 1 == "apple"
|
||||
@ -268,6 +291,8 @@ rec {
|
||||
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; abi = "gnu"; }
|
||||
else if hasPrefix "netbsd" (elemAt l 2)
|
||||
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; }
|
||||
else if (elem (elemAt l 2) ["eabi" "eabihf" "elf"])
|
||||
then { cpu = elemAt l 0; vendor = "unknown"; kernel = elemAt l 1; abi = elemAt l 2; }
|
||||
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)}
|
||||
|
7
lib/tests/check-eval.nix
Normal file
7
lib/tests/check-eval.nix
Normal file
@ -0,0 +1,7 @@
|
||||
# Throws an error if any of our lib tests fail.
|
||||
|
||||
let tests = [ "misc" "systems" ];
|
||||
all = builtins.concatLists (map (f: import (./. + "/${f}.nix")) tests);
|
||||
in if all == []
|
||||
then null
|
||||
else throw (builtins.toJSON all)
|
@ -112,7 +112,7 @@ runTests {
|
||||
storePathAppendix = isStorePath
|
||||
"${goodPath}/bin/python";
|
||||
nonAbsolute = isStorePath (concatStrings (tail (stringToCharacters goodPath)));
|
||||
asPath = isStorePath (builtins.toPath goodPath);
|
||||
asPath = isStorePath (/. + goodPath);
|
||||
otherPath = isStorePath "/something/else";
|
||||
otherVals = {
|
||||
attrset = isStorePath {};
|
||||
@ -236,6 +236,20 @@ runTests {
|
||||
};
|
||||
};
|
||||
|
||||
testOverrideExistingEmpty = {
|
||||
expr = overrideExisting {} { a = 1; };
|
||||
expected = {};
|
||||
};
|
||||
|
||||
testOverrideExistingDisjoint = {
|
||||
expr = overrideExisting { b = 2; } { a = 1; };
|
||||
expected = { b = 2; };
|
||||
};
|
||||
|
||||
testOverrideExistingOverride = {
|
||||
expr = overrideExisting { a = 3; b = 2; } { a = 1; };
|
||||
expected = { a = 1; b = 2; };
|
||||
};
|
||||
|
||||
# GENERATORS
|
||||
# these tests assume attributes are converted to lists
|
||||
@ -355,9 +369,10 @@ runTests {
|
||||
testToPretty = {
|
||||
expr = mapAttrs (const (generators.toPretty {})) rec {
|
||||
int = 42;
|
||||
float = 0.1337;
|
||||
bool = true;
|
||||
string = ''fno"rd'';
|
||||
path = /. + "/foo"; # toPath returns a string
|
||||
path = /. + "/foo";
|
||||
null_ = null;
|
||||
function = x: x;
|
||||
functionArgs = { arg ? 4, foo }: arg;
|
||||
@ -367,6 +382,7 @@ runTests {
|
||||
};
|
||||
expected = rec {
|
||||
int = "42";
|
||||
float = "~0.133700";
|
||||
bool = "true";
|
||||
string = ''"fno\"rd"'';
|
||||
path = "/foo";
|
||||
|
@ -12,20 +12,21 @@ let
|
||||
expected = lib.sort lib.lessThan y;
|
||||
};
|
||||
in with lib.systems.doubles; lib.runTests {
|
||||
all = assertTrue (mseteq all (linux ++ darwin ++ cygwin ++ freebsd ++ openbsd ++ netbsd ++ illumos));
|
||||
testall = mseteq all (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ windows);
|
||||
|
||||
arm = assertTrue (mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv7l-linux" ]);
|
||||
i686 = assertTrue (mseteq i686 [ "i686-linux" "i686-freebsd" "i686-netbsd" "i686-openbsd" "i686-cygwin" ]);
|
||||
mips = assertTrue (mseteq mips [ "mipsel-linux" ]);
|
||||
x86_64 = assertTrue (mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" ]);
|
||||
testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv7l-linux" ];
|
||||
testi686 = mseteq i686 [ "i686-linux" "i686-freebsd" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" ];
|
||||
testmips = mseteq mips [ "mipsel-linux" ];
|
||||
testx86_64 = mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" "x86_64-windows" ];
|
||||
|
||||
cygwin = assertTrue (mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ]);
|
||||
darwin = assertTrue (mseteq darwin [ "x86_64-darwin" ]);
|
||||
freebsd = assertTrue (mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ]);
|
||||
gnu = assertTrue (mseteq gnu (linux /* ++ kfreebsd ++ ... */));
|
||||
illumos = assertTrue (mseteq illumos [ "x86_64-solaris" ]);
|
||||
linux = assertTrue (mseteq linux [ "i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "mipsel-linux" ]);
|
||||
netbsd = assertTrue (mseteq netbsd [ "i686-netbsd" "x86_64-netbsd" ]);
|
||||
openbsd = assertTrue (mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ]);
|
||||
unix = assertTrue (mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos));
|
||||
testcygwin = mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ];
|
||||
testdarwin = mseteq darwin [ "x86_64-darwin" ];
|
||||
testfreebsd = mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ];
|
||||
testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */);
|
||||
testillumos = mseteq illumos [ "x86_64-solaris" ];
|
||||
testlinux = mseteq linux [ "i686-linux" "x86_64-linux" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "mipsel-linux" ];
|
||||
testnetbsd = mseteq netbsd [ "i686-netbsd" "x86_64-netbsd" ];
|
||||
testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ];
|
||||
testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ];
|
||||
testunix = mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ cygwin);
|
||||
}
|
||||
|
144
lib/trivial.nix
144
lib/trivial.nix
@ -9,23 +9,37 @@ rec {
|
||||
|
||||
Type: id :: a -> a
|
||||
*/
|
||||
id = x: x;
|
||||
id =
|
||||
# The value to return
|
||||
x: x;
|
||||
|
||||
/* The constant function
|
||||
Ignores the second argument.
|
||||
Or: Construct a function that always returns a static value.
|
||||
|
||||
Ignores the second argument. If called with only one argument,
|
||||
constructs a function that always returns a static value.
|
||||
|
||||
Type: const :: a -> b -> a
|
||||
Example:
|
||||
let f = const 5; in f 10
|
||||
=> 5
|
||||
*/
|
||||
const = x: y: x;
|
||||
const =
|
||||
# Value to return
|
||||
x:
|
||||
# Value to ignore
|
||||
y: x;
|
||||
|
||||
|
||||
## Named versions corresponding to some builtin operators.
|
||||
|
||||
/* Concatenate two lists */
|
||||
/* Concatenate two lists
|
||||
|
||||
Type: concat :: [a] -> [a] -> [a]
|
||||
|
||||
Example:
|
||||
concat [ 1 2 ] [ 3 4 ]
|
||||
=> [ 1 2 3 4 ]
|
||||
*/
|
||||
concat = x: y: x ++ y;
|
||||
|
||||
/* boolean “or” */
|
||||
@ -36,44 +50,57 @@ rec {
|
||||
|
||||
/* bitwise “and” */
|
||||
bitAnd = builtins.bitAnd
|
||||
or import ./zip-int-bits.nix
|
||||
(a: b: if a==1 && b==1 then 1 else 0);
|
||||
or (import ./zip-int-bits.nix
|
||||
(a: b: if a==1 && b==1 then 1 else 0));
|
||||
|
||||
/* bitwise “or” */
|
||||
bitOr = builtins.bitOr
|
||||
or import ./zip-int-bits.nix
|
||||
(a: b: if a==1 || b==1 then 1 else 0);
|
||||
or (import ./zip-int-bits.nix
|
||||
(a: b: if a==1 || b==1 then 1 else 0));
|
||||
|
||||
/* bitwise “xor” */
|
||||
bitXor = builtins.bitXor
|
||||
or import ./zip-int-bits.nix
|
||||
(a: b: if a!=b then 1 else 0);
|
||||
or (import ./zip-int-bits.nix
|
||||
(a: b: if a!=b then 1 else 0));
|
||||
|
||||
/* bitwise “not” */
|
||||
bitNot = builtins.sub (-1);
|
||||
|
||||
/* Convert a boolean to a string.
|
||||
Note that toString on a bool returns "1" and "".
|
||||
|
||||
This function uses the strings "true" and "false" to represent
|
||||
boolean values. Calling `toString` on a bool instead returns "1"
|
||||
and "" (sic!).
|
||||
|
||||
Type: boolToString :: bool -> string
|
||||
*/
|
||||
boolToString = b: if b then "true" else "false";
|
||||
|
||||
/* Merge two attribute sets shallowly, right side trumps left
|
||||
|
||||
mergeAttrs :: attrs -> attrs -> attrs
|
||||
|
||||
Example:
|
||||
mergeAttrs { a = 1; b = 2; } { b = 3; c = 4; }
|
||||
=> { a = 1; b = 3; c = 4; }
|
||||
*/
|
||||
mergeAttrs = x: y: x // y;
|
||||
mergeAttrs =
|
||||
# Left attribute set
|
||||
x:
|
||||
# Right attribute set (higher precedence for equal keys)
|
||||
y: x // y;
|
||||
|
||||
/* Flip the order of the arguments of a binary function.
|
||||
|
||||
Type: flip :: (a -> b -> c) -> (b -> a -> c)
|
||||
|
||||
Example:
|
||||
flip concat [1] [2]
|
||||
=> [ 2 1 ]
|
||||
*/
|
||||
flip = f: a: b: f b a;
|
||||
|
||||
/* Apply function if argument is non-null.
|
||||
/* Apply function if the supplied argument is non-null.
|
||||
|
||||
Example:
|
||||
mapNullable (x: x+1) null
|
||||
@ -81,7 +108,11 @@ rec {
|
||||
mapNullable (x: x+1) 22
|
||||
=> 23
|
||||
*/
|
||||
mapNullable = f: a: if isNull a then a else f a;
|
||||
mapNullable =
|
||||
# Function to call
|
||||
f:
|
||||
# Argument to check for null before passing it to `f`
|
||||
a: if isNull a then a else f a;
|
||||
|
||||
# Pull in some builtins not included elsewhere.
|
||||
inherit (builtins)
|
||||
@ -92,29 +123,58 @@ rec {
|
||||
|
||||
## nixpks version strings
|
||||
|
||||
# The current full nixpkgs version number.
|
||||
/* Returns the current full nixpkgs version number. */
|
||||
version = release + versionSuffix;
|
||||
|
||||
# The current nixpkgs version number as string.
|
||||
/* Returns the current nixpkgs release number as string. */
|
||||
release = lib.strings.fileContents ../.version;
|
||||
|
||||
# The current nixpkgs version suffix as string.
|
||||
/* Returns the current nixpkgs release code name.
|
||||
|
||||
On each release the first letter is bumped and a new animal is chosen
|
||||
starting with that new letter.
|
||||
*/
|
||||
codeName = "Koi";
|
||||
|
||||
/* Returns the current nixpkgs version suffix as string. */
|
||||
versionSuffix =
|
||||
let suffixFile = ../.version-suffix;
|
||||
in if pathExists suffixFile
|
||||
then lib.strings.fileContents suffixFile
|
||||
else "pre-git";
|
||||
|
||||
/* Attempts to return the the current revision of nixpkgs and
|
||||
returns the supplied default value otherwise.
|
||||
|
||||
Type: revisionWithDefault :: string -> string
|
||||
*/
|
||||
revisionWithDefault =
|
||||
# Default value to return if revision can not be determined
|
||||
default:
|
||||
let
|
||||
revisionFile = "${toString ./..}/.git-revision";
|
||||
gitRepo = "${toString ./..}/.git";
|
||||
in if lib.pathIsDirectory gitRepo
|
||||
then lib.commitIdFromGitRepo gitRepo
|
||||
else if lib.pathExists revisionFile then lib.fileContents revisionFile
|
||||
else default;
|
||||
|
||||
nixpkgsVersion = builtins.trace "`lib.nixpkgsVersion` is deprecated, use `lib.version` instead!" version;
|
||||
|
||||
# Whether we're being called by nix-shell.
|
||||
/* Determine whether the function is being called from inside a Nix
|
||||
shell.
|
||||
|
||||
Type: inNixShell :: bool
|
||||
*/
|
||||
inNixShell = builtins.getEnv "IN_NIX_SHELL" != "";
|
||||
|
||||
|
||||
## Integer operations
|
||||
|
||||
# Return minimum/maximum of two numbers.
|
||||
/* Return minimum of two numbers. */
|
||||
min = x: y: if x < y then x else y;
|
||||
|
||||
/* Return maximum of two numbers. */
|
||||
max = x: y: if x > y then x else y;
|
||||
|
||||
/* Integer modulus
|
||||
@ -148,8 +208,9 @@ rec {
|
||||
second subtype, compare elements of a single subtype with `yes`
|
||||
and `no` respectively.
|
||||
|
||||
Example:
|
||||
Type: (a -> bool) -> (a -> a -> int) -> (a -> a -> int) -> (a -> a -> int)
|
||||
|
||||
Example:
|
||||
let cmp = splitByAndCompare (hasPrefix "foo") compare compare; in
|
||||
|
||||
cmp "a" "z" => -1
|
||||
@ -160,31 +221,44 @@ rec {
|
||||
# while
|
||||
compare "fooa" "a" => 1
|
||||
*/
|
||||
splitByAndCompare = p: yes: no: a: b:
|
||||
splitByAndCompare =
|
||||
# Predicate
|
||||
p:
|
||||
# Comparison function if predicate holds for both values
|
||||
yes:
|
||||
# Comparison function if predicate holds for neither value
|
||||
no:
|
||||
# First value to compare
|
||||
a:
|
||||
# Second value to compare
|
||||
b:
|
||||
if p a
|
||||
then if p b then yes a b else -1
|
||||
else if p b then 1 else no a b;
|
||||
|
||||
|
||||
/* Reads a JSON file. */
|
||||
/* Reads a JSON file.
|
||||
|
||||
Type :: path -> any
|
||||
*/
|
||||
importJSON = path:
|
||||
builtins.fromJSON (builtins.readFile path);
|
||||
|
||||
|
||||
## Warnings and asserts
|
||||
## Warnings
|
||||
|
||||
/* See https://github.com/NixOS/nix/issues/749. Eventually we'd like these
|
||||
to expand to Nix builtins that carry metadata so that Nix can filter out
|
||||
the INFO messages without parsing the message string.
|
||||
# See https://github.com/NixOS/nix/issues/749. Eventually we'd like these
|
||||
# to expand to Nix builtins that carry metadata so that Nix can filter out
|
||||
# the INFO messages without parsing the message string.
|
||||
#
|
||||
# Usage:
|
||||
# {
|
||||
# foo = lib.warn "foo is deprecated" oldFoo;
|
||||
# }
|
||||
#
|
||||
# TODO: figure out a clever way to integrate location information from
|
||||
# something like __unsafeGetAttrPos.
|
||||
|
||||
Usage:
|
||||
{
|
||||
foo = lib.warn "foo is deprecated" oldFoo;
|
||||
}
|
||||
|
||||
TODO: figure out a clever way to integrate location information from
|
||||
something like __unsafeGetAttrPos.
|
||||
*/
|
||||
warn = msg: builtins.trace "WARNING: ${msg}";
|
||||
info = msg: builtins.trace "INFO: ${msg}";
|
||||
|
||||
|
@ -119,7 +119,9 @@ rec {
|
||||
let
|
||||
betweenDesc = lowest: highest:
|
||||
"${toString lowest} and ${toString highest} (both inclusive)";
|
||||
between = lowest: highest: assert lowest <= highest;
|
||||
between = lowest: highest:
|
||||
assert lib.assertMsg (lowest <= highest)
|
||||
"ints.between: lowest must be smaller than highest";
|
||||
addCheck int (x: x >= lowest && x <= highest) // {
|
||||
name = "intBetween";
|
||||
description = "integer between ${betweenDesc lowest highest}";
|
||||
@ -167,6 +169,9 @@ rec {
|
||||
# s32 = sign 32 4294967296;
|
||||
};
|
||||
|
||||
# Alias of u16 for a port number
|
||||
port = ints.u16;
|
||||
|
||||
float = mkOptionType rec {
|
||||
name = "float";
|
||||
description = "floating point number";
|
||||
@ -192,7 +197,10 @@ rec {
|
||||
# separator between the values).
|
||||
separatedString = sep: mkOptionType rec {
|
||||
name = "separatedString";
|
||||
description = "string";
|
||||
description = if sep == ""
|
||||
then "Concatenated string" # for types.string.
|
||||
else "strings concatenated with ${builtins.toJSON sep}"
|
||||
;
|
||||
check = isString;
|
||||
merge = loc: defs: concatStringsSep sep (getValues defs);
|
||||
functor = (defaultFunctor name) // {
|
||||
@ -439,7 +447,9 @@ rec {
|
||||
# Either value of type `finalType` or `coercedType`, the latter is
|
||||
# converted to `finalType` using `coerceFunc`.
|
||||
coercedTo = coercedType: coerceFunc: finalType:
|
||||
assert coercedType.getSubModules == null;
|
||||
assert lib.assertMsg (coercedType.getSubModules == null)
|
||||
"coercedTo: coercedType must not have submodules (it’s a ${
|
||||
coercedType.description})";
|
||||
mkOptionType rec {
|
||||
name = "coercedTo";
|
||||
description = "${finalType.description} or ${coercedType.description} convertible to it";
|
||||
|
@ -18,6 +18,11 @@
|
||||
for an example on how to work with this data.
|
||||
*/
|
||||
{
|
||||
"1000101" = {
|
||||
email = "jan.hrnko@satoshilabs.com";
|
||||
github = "1000101";
|
||||
name = "Jan Hrnko";
|
||||
};
|
||||
a1russell = {
|
||||
email = "adamlr6+pub@gmail.com";
|
||||
github = "a1russell";
|
||||
@ -68,6 +73,11 @@
|
||||
github = "acowley";
|
||||
name = "Anthony Cowley";
|
||||
};
|
||||
adamt = {
|
||||
email = "mail@adamtulinius.dk";
|
||||
github = "adamtulinius";
|
||||
name = "Adam Tulinius";
|
||||
};
|
||||
adelbertc = {
|
||||
email = "adelbertc@gmail.com";
|
||||
github = "adelbertc";
|
||||
@ -138,6 +148,11 @@
|
||||
github = "ahmedtd";
|
||||
name = "Taahir Ahmed";
|
||||
};
|
||||
ahuzik = {
|
||||
email = "ales.guzik@gmail.com";
|
||||
github = "alesguzik";
|
||||
name = "Ales Huzik";
|
||||
};
|
||||
aij = {
|
||||
email = "aij+git@mrph.org";
|
||||
github = "aij";
|
||||
@ -153,6 +168,11 @@
|
||||
github = "alexanderkjeldaas";
|
||||
name = "Alexander Kjeldaas";
|
||||
};
|
||||
akavel = {
|
||||
email = "czapkofan@gmail.com";
|
||||
github = "akavel";
|
||||
name = "Mateusz Czapliński";
|
||||
};
|
||||
akaWolf = {
|
||||
email = "akawolf0@gmail.com";
|
||||
github = "akaWolf";
|
||||
@ -201,6 +221,11 @@
|
||||
github = "alunduil";
|
||||
name = "Alex Brandt";
|
||||
};
|
||||
amar1729 = {
|
||||
email = "amar.paul16@gmail.com";
|
||||
github = "amar1729";
|
||||
name = "Amar Paul";
|
||||
};
|
||||
ambrop72 = {
|
||||
email = "ambrop7@gmail.com";
|
||||
github = "ambrop72";
|
||||
@ -216,6 +241,11 @@
|
||||
github = "amiloradovsky";
|
||||
name = "Andrew Miloradovsky";
|
||||
};
|
||||
aminb = {
|
||||
email = "amin@aminb.org";
|
||||
github = "aminb";
|
||||
name = "Amin Bandali";
|
||||
};
|
||||
aminechikhaoui = {
|
||||
email = "amine.chikhaoui91@gmail.com";
|
||||
github = "AmineChikhaoui";
|
||||
@ -227,7 +257,7 @@
|
||||
name = "Andrew Morsillo";
|
||||
};
|
||||
AndersonTorres = {
|
||||
email = "torres.anderson.85@gmail.com";
|
||||
email = "torres.anderson.85@protonmail.com";
|
||||
github = "AndersonTorres";
|
||||
name = "Anderson Torres";
|
||||
};
|
||||
@ -371,11 +401,31 @@
|
||||
github = "aszlig";
|
||||
name = "aszlig";
|
||||
};
|
||||
atnnn = {
|
||||
email = "etienne@atnnn.com";
|
||||
github = "atnnn";
|
||||
name = "Etienne Laurin";
|
||||
};
|
||||
auntie = {
|
||||
email = "auntieNeo@gmail.com";
|
||||
github = "auntie";
|
||||
name = "Jonathan Glines";
|
||||
};
|
||||
avaq = {
|
||||
email = "avaq+nixos@xs4all.nl";
|
||||
github = "avaq";
|
||||
name = "Aldwin Vlasblom";
|
||||
};
|
||||
avery = {
|
||||
email = "averyl+nixos@protonmail.com";
|
||||
github = "AveryLychee";
|
||||
name = "Avery Lychee";
|
||||
};
|
||||
averelld = {
|
||||
email = "averell+nixos@rxd4.com";
|
||||
github = "averelld";
|
||||
name = "averelld";
|
||||
};
|
||||
avnik = {
|
||||
email = "avn@avnik.info";
|
||||
github = "avnik";
|
||||
@ -470,6 +520,11 @@
|
||||
github = "bennofs";
|
||||
name = "Benno Fünfstück";
|
||||
};
|
||||
benpye = {
|
||||
email = "ben@curlybracket.co.uk";
|
||||
github = "benpye";
|
||||
name = "Ben Pye";
|
||||
};
|
||||
benwbooth = {
|
||||
email = "benwbooth@gmail.com";
|
||||
github = "benwbooth";
|
||||
@ -500,6 +555,11 @@
|
||||
github = "bgamari";
|
||||
name = "Ben Gamari";
|
||||
};
|
||||
bhall = {
|
||||
email = "brendan.j.hall@bath.edu";
|
||||
github = "brendan-hall";
|
||||
name = "Brendan Hall";
|
||||
};
|
||||
bhipple = {
|
||||
email = "bhipple@protonmail.com";
|
||||
github = "bhipple";
|
||||
@ -579,6 +639,11 @@
|
||||
github = "bramd";
|
||||
name = "Bram Duvigneau";
|
||||
};
|
||||
braydenjw = {
|
||||
email = "nixpkgs@willenborg.ca";
|
||||
github = "braydenjw";
|
||||
name = "Brayden Willenborg";
|
||||
};
|
||||
brian-dawn = {
|
||||
email = "brian.t.dawn@gmail.com";
|
||||
github = "brian-dawn";
|
||||
@ -633,6 +698,11 @@
|
||||
github = "campadrenalin";
|
||||
name = "Philip Horger";
|
||||
};
|
||||
candeira = {
|
||||
email = "javier@candeira.com";
|
||||
github = "candeira";
|
||||
name = "Javier Candeira";
|
||||
};
|
||||
canndrew = {
|
||||
email = "shum@canndrew.org";
|
||||
github = "canndrew";
|
||||
@ -678,6 +748,11 @@
|
||||
github = "Chaddai";
|
||||
name = "Chaddaï Fouché";
|
||||
};
|
||||
chaduffy = {
|
||||
email = "charles@dyfis.net";
|
||||
github = "charles-dyfis-net";
|
||||
name = "Charles Duffy";
|
||||
};
|
||||
changlinli = {
|
||||
email = "mail@changlinli.com";
|
||||
github = "changlinli";
|
||||
@ -702,6 +777,11 @@
|
||||
github = "ChengCat";
|
||||
name = "Yucheng Zhang";
|
||||
};
|
||||
chessai = {
|
||||
email = "chessai1996@gmail.com";
|
||||
github = "chessai";
|
||||
name = "Daniel Cartwright";
|
||||
};
|
||||
chiiruno = {
|
||||
email = "okinan@protonmail.com";
|
||||
github = "chiiruno";
|
||||
@ -912,6 +992,11 @@
|
||||
github = "danielfullmer";
|
||||
name = "Daniel Fullmer";
|
||||
};
|
||||
das-g = {
|
||||
email = "nixpkgs@raphael.dasgupta.ch";
|
||||
github = "das-g";
|
||||
name = "Raphael Das Gupta";
|
||||
};
|
||||
das_j = {
|
||||
email = "janne@hess.ooo";
|
||||
github = "dasJ";
|
||||
@ -956,6 +1041,11 @@
|
||||
github = "deepfire";
|
||||
name = "Kosyrev Serge";
|
||||
};
|
||||
delroth = {
|
||||
email = "delroth@gmail.com";
|
||||
github = "delroth";
|
||||
name = "Pierre Bourdon";
|
||||
};
|
||||
deltaevo = {
|
||||
email = "deltaduartedavid@gmail.com";
|
||||
github = "DeltaEvo";
|
||||
@ -1110,6 +1200,11 @@
|
||||
github = "dtzWill";
|
||||
name = "Will Dietz";
|
||||
};
|
||||
dysinger = {
|
||||
email = "tim@dysinger.net";
|
||||
github = "dysinger";
|
||||
name = "Tim Dysinger";
|
||||
};
|
||||
dywedir = {
|
||||
email = "dywedir@protonmail.ch";
|
||||
github = "dywedir";
|
||||
@ -1165,6 +1260,11 @@
|
||||
github = "eduarrrd";
|
||||
name = "Eduard Bachmakov";
|
||||
};
|
||||
edude03 = {
|
||||
email = "michael@melenion.com";
|
||||
github = "edude03";
|
||||
name = "Michael Francis";
|
||||
};
|
||||
edwtjo = {
|
||||
email = "ed@cflags.cc";
|
||||
github = "edwtjo";
|
||||
@ -1224,6 +1324,11 @@
|
||||
github = "ellis";
|
||||
name = "Ellis Whitehead";
|
||||
};
|
||||
elseym = {
|
||||
email = "elseym@me.com";
|
||||
github = "elseym";
|
||||
name = "Simon Waibl";
|
||||
};
|
||||
elvishjerricco = {
|
||||
email = "elvishjerricco@gmail.com";
|
||||
github = "ElvishJerricco";
|
||||
@ -1307,6 +1412,11 @@
|
||||
github = "etu";
|
||||
name = "Elis Hirwing";
|
||||
};
|
||||
evck = {
|
||||
email = "eric@evenchick.com";
|
||||
github = "ericevenchick";
|
||||
name = "Eric Evenchick";
|
||||
};
|
||||
exfalso = {
|
||||
email = "0slemi0@gmail.com";
|
||||
github = "exfalso";
|
||||
@ -1327,6 +1437,11 @@
|
||||
github = "expipiplus1";
|
||||
name = "Joe Hermaszewski";
|
||||
};
|
||||
f--t = {
|
||||
email = "git@f-t.me";
|
||||
github = "f--t";
|
||||
name = "f--t";
|
||||
};
|
||||
f-breidenstein = {
|
||||
email = "mail@felixbreidenstein.de";
|
||||
github = "f-breidenstein";
|
||||
@ -1442,6 +1557,11 @@
|
||||
github = "ftrvxmtrx";
|
||||
name = "Siarhei Zirukin";
|
||||
};
|
||||
fuerbringer = {
|
||||
email = "severin@fuerbringer.info";
|
||||
github = "fuerbringer";
|
||||
name = "Severin Fürbringer";
|
||||
};
|
||||
funfunctor = {
|
||||
email = "eocallaghan@alterapraxis.com";
|
||||
name = "Edward O'Callaghan";
|
||||
@ -1451,6 +1571,11 @@
|
||||
github = "fuuzetsu";
|
||||
name = "Mateusz Kowalczyk";
|
||||
};
|
||||
fuwa = {
|
||||
email = "echowss@gmail.com";
|
||||
github = "fuwa0529";
|
||||
name = "Haruka Akiyama";
|
||||
};
|
||||
fuzzy-id = {
|
||||
email = "hacking+nixos@babibo.de";
|
||||
name = "Thomas Bach";
|
||||
@ -1610,6 +1735,11 @@
|
||||
github = "hamhut1066";
|
||||
name = "Hamish Hutchings";
|
||||
};
|
||||
haslersn = {
|
||||
email = "haslersn@fius.informatik.uni-stuttgart.de";
|
||||
github = "haslersn";
|
||||
name = "Sebastian Hasler";
|
||||
};
|
||||
havvy = {
|
||||
email = "ryan.havvy@gmail.com";
|
||||
github = "havvy";
|
||||
@ -1664,6 +1794,11 @@
|
||||
email = "t@larkery.com";
|
||||
name = "Tom Hinton";
|
||||
};
|
||||
hlolli = {
|
||||
email = "hlolli@gmail.com";
|
||||
github = "hlolli";
|
||||
name = "Hlodver Sigurdsson";
|
||||
};
|
||||
hodapp = {
|
||||
email = "hodapp87@gmail.com";
|
||||
github = "Hodapp87";
|
||||
@ -1759,6 +1894,11 @@
|
||||
github = "ironpinguin";
|
||||
name = "Michele Catalano";
|
||||
};
|
||||
ivan = {
|
||||
email = "ivan@ludios.org";
|
||||
github = "ivan";
|
||||
name = "Ivan Kozik";
|
||||
};
|
||||
ivan-tkatchev = {
|
||||
email = "tkatchev@gmail.com";
|
||||
name = "Ivan Tkatchev";
|
||||
@ -1788,6 +1928,11 @@
|
||||
github = "jagajaga";
|
||||
name = "Arseniy Seroka";
|
||||
};
|
||||
jakelogemann = {
|
||||
email = "jake.logemann@gmail.com";
|
||||
github = "jakelogemann";
|
||||
name = "Jake Logemann";
|
||||
};
|
||||
jammerful = {
|
||||
email = "jammerful@gmail.com";
|
||||
github = "jammerful";
|
||||
@ -1832,6 +1977,11 @@
|
||||
github = "jdagilliland";
|
||||
name = "Jason Gilliland";
|
||||
};
|
||||
jdehaas = {
|
||||
email = "qqlq@nullptr.club";
|
||||
github = "jeroendehaas";
|
||||
name = "Jeroen de Haas";
|
||||
};
|
||||
jefdaj = {
|
||||
email = "jefdaj@gmail.com";
|
||||
github = "jefdaj";
|
||||
@ -1847,6 +1997,16 @@
|
||||
github = "jerith666";
|
||||
name = "Matt McHenry";
|
||||
};
|
||||
jeschli = {
|
||||
email = "jeschli@gmail.com";
|
||||
github = "jeschli";
|
||||
name = "Markus Hihn";
|
||||
};
|
||||
jethro = {
|
||||
email = "jethrokuan95@gmail.com";
|
||||
github = "jethrokuan";
|
||||
name = "Jethro Kuan";
|
||||
};
|
||||
jfb = {
|
||||
email = "james@yamtime.com";
|
||||
github = "tftio";
|
||||
@ -1887,6 +2047,11 @@
|
||||
github = "jhhuh";
|
||||
name = "Ji-Haeng Huh";
|
||||
};
|
||||
jhillyerd = {
|
||||
email = "james+nixos@hillyerd.com";
|
||||
github = "jhillyerd";
|
||||
name = "James Hillyerd";
|
||||
};
|
||||
jirkamarsik = {
|
||||
email = "jiri.marsik89@gmail.com";
|
||||
github = "jirkamarsik";
|
||||
@ -1902,6 +2067,11 @@
|
||||
github = "jluttine";
|
||||
name = "Jaakko Luttinen";
|
||||
};
|
||||
jmagnusj = {
|
||||
email = "jmagnusj@gmail.com";
|
||||
github = "magnusjonsson";
|
||||
name = "Johan Magnus Jonsson";
|
||||
};
|
||||
jmettes = {
|
||||
email = "jonathan@jmettes.com";
|
||||
github = "jmettes";
|
||||
@ -2098,6 +2268,11 @@
|
||||
github = "kiloreux";
|
||||
name = "Kiloreux Emperex";
|
||||
};
|
||||
kimburgess = {
|
||||
email = "kim@acaprojects.com";
|
||||
github = "kimburgess";
|
||||
name = "Kim Burgess";
|
||||
};
|
||||
kini = {
|
||||
email = "keshav.kini@gmail.com";
|
||||
github = "kini";
|
||||
@ -2124,6 +2299,11 @@
|
||||
github = "knedlsepp";
|
||||
name = "Josef Kemetmüller";
|
||||
};
|
||||
knl = {
|
||||
email = "nikola@knezevic.co";
|
||||
github = "knl";
|
||||
name = "Nikola Knežević";
|
||||
};
|
||||
konimex = {
|
||||
email = "herdiansyah@netc.eu";
|
||||
github = "konimex";
|
||||
@ -2154,6 +2334,11 @@
|
||||
github = "krav";
|
||||
name = "Kristoffer Thømt Ravneberg";
|
||||
};
|
||||
kroell = {
|
||||
email = "nixosmainter@makroell.de";
|
||||
github = "rokk4";
|
||||
name = "Matthias Axel Kröll";
|
||||
};
|
||||
kristoff3r = {
|
||||
email = "k.soeholm@gmail.com";
|
||||
github = "kristoff3r";
|
||||
@ -2294,6 +2479,11 @@
|
||||
github = "listx";
|
||||
name = "Linus Arver";
|
||||
};
|
||||
lionello = {
|
||||
email = "lio@lunesu.com";
|
||||
github = "lionello";
|
||||
name = "Lionello Lunesu";
|
||||
};
|
||||
lluchs = {
|
||||
email = "lukas.werling@gmail.com";
|
||||
github = "lluchs";
|
||||
@ -2397,6 +2587,11 @@
|
||||
github = "ma27";
|
||||
name = "Maximilian Bosch";
|
||||
};
|
||||
ma9e = {
|
||||
email = "sean@lfo.team";
|
||||
github = "ma9e";
|
||||
name = "Sean Haugh";
|
||||
};
|
||||
madjar = {
|
||||
email = "georges.dubus@compiletoi.net";
|
||||
github = "madjar";
|
||||
@ -2531,6 +2726,11 @@
|
||||
github = "mdaiter";
|
||||
name = "Matthew S. Daiter";
|
||||
};
|
||||
mdevlamynck = {
|
||||
email = "matthias.devlamynck@mailoo.org";
|
||||
github = "mdevlamynck";
|
||||
name = "Matthias Devlamynck";
|
||||
};
|
||||
meditans = {
|
||||
email = "meditans@gmail.com";
|
||||
github = "meditans";
|
||||
@ -2556,6 +2756,11 @@
|
||||
github = "melsigl";
|
||||
name = "Melanie B. Sigl";
|
||||
};
|
||||
melkor333 = {
|
||||
email = "samuel@ton-kunst.ch";
|
||||
github = "melkor333";
|
||||
name = "Samuel Ruprecht";
|
||||
};
|
||||
metabar = {
|
||||
email = "softs@metabarcoding.org";
|
||||
name = "Celine Mercier";
|
||||
@ -2565,6 +2770,11 @@
|
||||
github = "mgdelacroix";
|
||||
name = "Miguel de la Cruz";
|
||||
};
|
||||
mgregoire = {
|
||||
email = "gregoire@martinache.net";
|
||||
github = "M-Gregoire";
|
||||
name = "Gregoire Martinache";
|
||||
};
|
||||
mgttlinger = {
|
||||
email = "megoettlinger@gmail.com";
|
||||
github = "mgttlinger";
|
||||
@ -2808,6 +3018,11 @@
|
||||
github = "muflax";
|
||||
name = "Stefan Dorn";
|
||||
};
|
||||
mvnetbiz = {
|
||||
email = "mvnetbiz@gmail.com";
|
||||
github = "mvnetbiz";
|
||||
name = "Matt Votava";
|
||||
};
|
||||
myrl = {
|
||||
email = "myrl.0xf@gmail.com";
|
||||
github = "myrl";
|
||||
@ -2862,6 +3077,11 @@
|
||||
github = "nequissimus";
|
||||
name = "Tim Steinbach";
|
||||
};
|
||||
nikitavoloboev = {
|
||||
email = "nikita.voloboev@gmail.com";
|
||||
github = "nikitavoloboev";
|
||||
name = "Nikita Voloboev";
|
||||
};
|
||||
nfjinjing = {
|
||||
email = "nfjinjing@gmail.com";
|
||||
github = "nfjinjing";
|
||||
@ -2987,7 +3207,7 @@
|
||||
name = "Oliver Dunkl";
|
||||
};
|
||||
offline = {
|
||||
email = "jakahudoklin@gmail.com";
|
||||
email = "jaka@x-truder.net";
|
||||
github = "offlinehacker";
|
||||
name = "Jaka Hudoklin";
|
||||
};
|
||||
@ -3015,6 +3235,11 @@
|
||||
github = "olynch";
|
||||
name = "Owen Lynch";
|
||||
};
|
||||
OPNA2608 = {
|
||||
email = "christoph.neidahl@gmail.com";
|
||||
github = "OPNA2608";
|
||||
name = "Christoph Neidahl";
|
||||
};
|
||||
orbekk = {
|
||||
email = "kjetil.orbekk@gmail.com";
|
||||
github = "orbekk";
|
||||
@ -3050,6 +3275,16 @@
|
||||
github = "oyren";
|
||||
name = "Moritz Scheuren";
|
||||
};
|
||||
pacien = {
|
||||
email = "b4gx3q.nixpkgs@pacien.net";
|
||||
github = "pacien";
|
||||
name = "Pacien Tran-Girard";
|
||||
};
|
||||
paddygord = {
|
||||
email = "pgpatrickgordon@gmail.com";
|
||||
github = "paddygord";
|
||||
name = "Patrick Gordon";
|
||||
};
|
||||
paholg = {
|
||||
email = "paho@paholg.com";
|
||||
github = "paholg";
|
||||
@ -3224,6 +3459,11 @@
|
||||
github = "pmyjavec";
|
||||
name = "Pauly Myjavec";
|
||||
};
|
||||
pnelson = {
|
||||
email = "me@pnelson.ca";
|
||||
github = "pnelson";
|
||||
name = "Philip Nelson";
|
||||
};
|
||||
pneumaticat = {
|
||||
email = "kevin@potatofrom.space";
|
||||
github = "pneumaticat";
|
||||
@ -3259,6 +3499,11 @@
|
||||
github = "proglodyte";
|
||||
name = "Proglodyte";
|
||||
};
|
||||
prusnak = {
|
||||
email = "stick@gk2.sk";
|
||||
github = "prusnak";
|
||||
name = "Pavol Rusnak";
|
||||
};
|
||||
pshendry = {
|
||||
email = "paul@pshendry.com";
|
||||
github = "pshendry";
|
||||
@ -3396,6 +3641,11 @@
|
||||
github = "relrod";
|
||||
name = "Ricky Elrod";
|
||||
};
|
||||
renatoGarcia = {
|
||||
email = "fgarcia.renato@gmail.com";
|
||||
github = "renatoGarcia";
|
||||
name = "Renato Garcia";
|
||||
};
|
||||
renzo = {
|
||||
email = "renzocarbonara@gmail.com";
|
||||
github = "k0001";
|
||||
@ -3506,6 +3756,11 @@
|
||||
github = "roosemberth";
|
||||
name = "Roosembert (Roosemberth) Palacios";
|
||||
};
|
||||
royneary = {
|
||||
email = "christian@ulrich.earth";
|
||||
github = "royneary";
|
||||
name = "Christian Ulrich";
|
||||
};
|
||||
rprospero = {
|
||||
email = "rprospero+nix@gmail.com";
|
||||
github = "rprospero";
|
||||
@ -3621,6 +3876,16 @@
|
||||
github = "sauyon";
|
||||
name = "Sauyon Lee";
|
||||
};
|
||||
sboosali = {
|
||||
email = "SamBoosalis@gmail.com";
|
||||
github = "sboosali";
|
||||
name = "Sam Boosalis";
|
||||
};
|
||||
scalavision = {
|
||||
email = "scalavision@gmail.com";
|
||||
github = "scalavision";
|
||||
name = "Tom Sorlie";
|
||||
};
|
||||
schmitthenner = {
|
||||
email = "development@schmitthenner.eu";
|
||||
github = "fkz";
|
||||
@ -3645,6 +3910,11 @@
|
||||
github = "scolobb";
|
||||
name = "Sergiu Ivanov";
|
||||
};
|
||||
screendriver = {
|
||||
email = "nix@echooff.de";
|
||||
github = "screendriver";
|
||||
name = "Christian Rackerseder";
|
||||
};
|
||||
Scriptkiddi = {
|
||||
email = "nixos@scriptkiddi.de";
|
||||
github = "scriptkiddi";
|
||||
@ -3685,6 +3955,11 @@
|
||||
github = "seppeljordan";
|
||||
name = "Sebastian Jordan";
|
||||
};
|
||||
seqizz = {
|
||||
email = "seqizz@gmail.com";
|
||||
github = "seqizz";
|
||||
name = "Gurkan Gur";
|
||||
};
|
||||
sfrijters = {
|
||||
email = "sfrijters@gmail.com";
|
||||
github = "sfrijters";
|
||||
@ -3755,6 +4030,11 @@
|
||||
github = "sjagoe";
|
||||
name = "Simon Jagoe";
|
||||
};
|
||||
sjau = {
|
||||
email = "nixos@sjau.ch";
|
||||
github = "sjau";
|
||||
name = "Stephan Jau";
|
||||
};
|
||||
sjmackenzie = {
|
||||
email = "setori88@gmail.com";
|
||||
github = "sjmackenzie";
|
||||
@ -3823,6 +4103,11 @@
|
||||
github = "spacefrogg";
|
||||
name = "Michael Raitza";
|
||||
};
|
||||
spacekookie = {
|
||||
email = "kookie@spacekookie.de";
|
||||
github = "spacekookie";
|
||||
name = "Katharina Fey";
|
||||
};
|
||||
spencerjanssen = {
|
||||
email = "spencerjanssen@gmail.com";
|
||||
github = "spencerjanssen";
|
||||
@ -3888,6 +4173,11 @@
|
||||
github = "StillerHarpo";
|
||||
name = "Florian Engel";
|
||||
};
|
||||
stites = {
|
||||
email = "sam@stites.io";
|
||||
github = "stites";
|
||||
name = "Sam Stites";
|
||||
};
|
||||
stumoss = {
|
||||
email = "samoss@gmail.com";
|
||||
github = "stumoss";
|
||||
@ -3953,6 +4243,11 @@
|
||||
github = "sztupi";
|
||||
name = "Attila Sztupak";
|
||||
};
|
||||
t184256 = {
|
||||
email = "monk@unboiled.info";
|
||||
github = "t184256";
|
||||
name = "Alexander Sosedkin";
|
||||
};
|
||||
tadfisher = {
|
||||
email = "tadfisher@gmail.com";
|
||||
github = "tadfisher";
|
||||
@ -3993,6 +4288,16 @@
|
||||
github = "taku0";
|
||||
name = "Takuo Yonezawa";
|
||||
};
|
||||
talyz = {
|
||||
email = "kim.lindberger@gmail.com";
|
||||
github = "talyz";
|
||||
name = "Kim Lindberger";
|
||||
};
|
||||
taneb = {
|
||||
email = "nvd1234@gmail.com";
|
||||
github = "Taneb";
|
||||
name = "Nathan van Doorn";
|
||||
};
|
||||
tari = {
|
||||
email = "peter@taricorp.net";
|
||||
github = "tari";
|
||||
@ -4008,11 +4313,6 @@
|
||||
github = "tazjin";
|
||||
name = "Vincent Ambo";
|
||||
};
|
||||
TealG = {
|
||||
email = "~@Teal.Gr";
|
||||
github = "TealG";
|
||||
name = "Teal Gaure";
|
||||
};
|
||||
teh = {
|
||||
email = "tehunger@gmail.com";
|
||||
github = "teh";
|
||||
@ -4038,6 +4338,11 @@
|
||||
github = "tex";
|
||||
name = "Milan Svoboda";
|
||||
};
|
||||
tg-x = {
|
||||
email = "*@tg-x.net";
|
||||
github = "tg-x";
|
||||
name = "TG ⊗ Θ";
|
||||
};
|
||||
thall = {
|
||||
email = "niclas.thall@gmail.com";
|
||||
github = "thall";
|
||||
@ -4153,6 +4458,11 @@
|
||||
github = "tomsmeets";
|
||||
name = "Tom Smeets";
|
||||
};
|
||||
toonn = {
|
||||
email = "nnoot@toonn.io";
|
||||
github = "toonn";
|
||||
name = "Toon Nolten";
|
||||
};
|
||||
travisbhartwell = {
|
||||
email = "nafai@travishartwell.net";
|
||||
github = "travisbhartwell";
|
||||
@ -4237,6 +4547,11 @@
|
||||
github = "uri-canva";
|
||||
name = "Uri Baghin";
|
||||
};
|
||||
uskudnik = {
|
||||
email = "urban.skudnik@gmail.com";
|
||||
github = "uskudnik";
|
||||
name = "Urban Skudnik";
|
||||
};
|
||||
utdemir = {
|
||||
email = "me@utdemir.com";
|
||||
github = "utdemir";
|
||||
@ -4381,6 +4696,11 @@
|
||||
github = "vrthra";
|
||||
name = "Rahul Gopinath";
|
||||
};
|
||||
vskilet = {
|
||||
email = "victor@sene.ovh";
|
||||
github = "vskilet";
|
||||
name = "Victor SENE";
|
||||
};
|
||||
vyp = {
|
||||
email = "elisp.vim@gmail.com";
|
||||
github = "vyp";
|
||||
@ -4458,6 +4778,11 @@
|
||||
github = "wucke13";
|
||||
name = "Wucke";
|
||||
};
|
||||
wykurz = {
|
||||
email = "wykurz@gmail.com";
|
||||
github = "wykurz";
|
||||
name = "Mateusz Wykurz";
|
||||
};
|
||||
wyvie = {
|
||||
email = "elijahrum@gmail.com";
|
||||
github = "wyvie";
|
||||
@ -4508,13 +4833,18 @@
|
||||
github = "y0no";
|
||||
name = "Yoann Ono";
|
||||
};
|
||||
yarny = {
|
||||
email = "41838844+Yarny0@users.noreply.github.com";
|
||||
github = "Yarny0";
|
||||
name = "Yarny";
|
||||
};
|
||||
yarr = {
|
||||
email = "savraz@gmail.com";
|
||||
github = "Eternity-Yarr";
|
||||
name = "Dmitry V.";
|
||||
};
|
||||
yegortimoshenko = {
|
||||
email = "yegortimoshenko@gmail.com";
|
||||
email = "yegortimoshenko@riseup.net";
|
||||
github = "yegortimoshenko";
|
||||
name = "Yegor Timoshenko";
|
||||
};
|
||||
@ -4563,6 +4893,11 @@
|
||||
github = "maggesi";
|
||||
name = "Marco Maggesi";
|
||||
};
|
||||
zachcoyle = {
|
||||
email = "zach.coyle@gmail.com";
|
||||
github = "zachcoyle";
|
||||
name = "Zach Coyle";
|
||||
};
|
||||
zagy = {
|
||||
email = "cz@flyingcircus.io";
|
||||
github = "zagy";
|
||||
@ -4573,6 +4908,11 @@
|
||||
github = "umazalakain";
|
||||
name = "Unai Zalakain";
|
||||
};
|
||||
zaninime = {
|
||||
email = "francesco@zanini.me";
|
||||
github = "zaninime";
|
||||
name = "Francesco Zanini";
|
||||
};
|
||||
zarelit = {
|
||||
email = "david@zarel.net";
|
||||
github = "zarelit";
|
||||
@ -4627,4 +4967,9 @@
|
||||
github = "zzamboni";
|
||||
name = "Diego Zamboni";
|
||||
};
|
||||
mredaelli = {
|
||||
email = "massimo@typish.io";
|
||||
github = "mredaelli";
|
||||
name = "Massimo Redaelli";
|
||||
};
|
||||
}
|
||||
|
@ -1,361 +1,3 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ packaging requests toolz ])" -p git
|
||||
#!/bin/sh
|
||||
exec nix-shell -p "python3.withPackages(ps: with ps; [ packaging requests toolz ])" -p git --run pkgs/development/interpreters/python/update-python-libraries/update-python-libraries.py
|
||||
|
||||
"""
|
||||
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
|
||||
from concurrent.futures import ThreadPoolExecutor as Pool
|
||||
from packaging.version import Version as _Version
|
||||
from packaging.version import InvalidVersion
|
||||
from packaging.specifiers import SpecifierSet
|
||||
import collections
|
||||
import subprocess
|
||||
|
||||
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."""
|
||||
|
||||
PRERELEASES = False
|
||||
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
class Version(_Version, collections.abc.Sequence):
|
||||
|
||||
def __init__(self, version):
|
||||
super().__init__(version)
|
||||
# We cannot use `str(Version(0.04.21))` because that becomes `0.4.21`
|
||||
# https://github.com/avian2/unidecode/issues/13#issuecomment-354538882
|
||||
self.raw_version = version
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self._version.release[i]
|
||||
|
||||
def __len__(self):
|
||||
return len(self._version.release)
|
||||
|
||||
def __iter__(self):
|
||||
yield from self._version.release
|
||||
|
||||
|
||||
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))
|
||||
|
||||
|
||||
SEMVER = {
|
||||
'major' : 0,
|
||||
'minor' : 1,
|
||||
'patch' : 2,
|
||||
}
|
||||
|
||||
|
||||
def _determine_latest_version(current_version, target, versions):
|
||||
"""Determine latest version, given `target`.
|
||||
"""
|
||||
current_version = Version(current_version)
|
||||
|
||||
def _parse_versions(versions):
|
||||
for v in versions:
|
||||
try:
|
||||
yield Version(v)
|
||||
except InvalidVersion:
|
||||
pass
|
||||
|
||||
versions = _parse_versions(versions)
|
||||
|
||||
index = SEMVER[target]
|
||||
|
||||
ceiling = list(current_version[0:index])
|
||||
if len(ceiling) == 0:
|
||||
ceiling = None
|
||||
else:
|
||||
ceiling[-1]+=1
|
||||
ceiling = Version(".".join(map(str, ceiling)))
|
||||
|
||||
# We do not want prereleases
|
||||
versions = SpecifierSet(prereleases=PRERELEASES).filter(versions)
|
||||
|
||||
if ceiling is not None:
|
||||
versions = SpecifierSet(f"<{ceiling}").filter(versions)
|
||||
|
||||
return (max(sorted(versions))).raw_version
|
||||
|
||||
|
||||
def _get_latest_version_pypi(package, extension, current_version, target):
|
||||
"""Get latest version and hash from PyPI."""
|
||||
url = "{}/{}/json".format(INDEX, package)
|
||||
json = _fetch_page(url)
|
||||
|
||||
versions = json['releases'].keys()
|
||||
version = _determine_latest_version(current_version, target, versions)
|
||||
|
||||
try:
|
||||
releases = json['releases'][version]
|
||||
except KeyError as e:
|
||||
raise KeyError('Could not find version {} for {}'.format(version, package)) from e
|
||||
for release in releases:
|
||||
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, current_version, target):
|
||||
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:
|
||||
src_format = _get_unique_value('format', text)
|
||||
except ValueError as e:
|
||||
src_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 src_format is None:
|
||||
src_format = 'setuptools'
|
||||
elif src_format == 'flit':
|
||||
raise ValueError("Don't know how to update a Flit package.")
|
||||
extension = FORMATS[src_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, target):
|
||||
|
||||
# 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 = FETCHERS[fetcher](pname, extension, version, target)
|
||||
|
||||
if new_version == version:
|
||||
logging.info("Path {}: no update available for {}.".format(path, pname))
|
||||
return False
|
||||
elif Version(new_version) <= Version(version):
|
||||
raise ValueError("downgrade for {}.".format(pname))
|
||||
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))
|
||||
|
||||
result = {
|
||||
'path' : path,
|
||||
'target': target,
|
||||
'pname': pname,
|
||||
'old_version' : version,
|
||||
'new_version' : new_version,
|
||||
#'fetcher' : fetcher,
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _update(path, target):
|
||||
|
||||
# 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, target)
|
||||
except ValueError as e:
|
||||
logging.warning("Path {}: {}".format(path, e))
|
||||
return False
|
||||
|
||||
|
||||
def _commit(path, pname, old_version, new_version, **kwargs):
|
||||
"""Commit result.
|
||||
"""
|
||||
|
||||
msg = f'python: {pname}: {old_version} -> {new_version}'
|
||||
|
||||
try:
|
||||
subprocess.check_call(['git', 'add', path])
|
||||
subprocess.check_call(['git', 'commit', '-m', msg])
|
||||
except subprocess.CalledProcessError as e:
|
||||
subprocess.check_call(['git', 'checkout', path])
|
||||
raise subprocess.CalledProcessError(f'Could not commit {path}') from e
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('package', type=str, nargs='+')
|
||||
parser.add_argument('--target', type=str, choices=SEMVER.keys(), default='major')
|
||||
parser.add_argument('--commit', action='store_true', help='Create a commit for each package update')
|
||||
|
||||
args = parser.parse_args()
|
||||
target = args.target
|
||||
|
||||
packages = list(map(os.path.abspath, args.package))
|
||||
|
||||
logging.info("Updating packages...")
|
||||
|
||||
# Use threads to update packages concurrently
|
||||
with Pool() as p:
|
||||
results = list(p.map(lambda pkg: _update(pkg, target), packages))
|
||||
|
||||
logging.info("Finished updating packages.")
|
||||
|
||||
# Commits are created sequentially.
|
||||
if args.commit:
|
||||
logging.info("Committing updates...")
|
||||
list(map(lambda x: _commit(**x), filter(bool, results)))
|
||||
logging.info("Finished committing updates")
|
||||
|
||||
count = sum(map(bool, results))
|
||||
logging.info("{} package(s) updated".format(count))
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -1,6 +1,8 @@
|
||||
{ package ? null
|
||||
, maintainer ? null
|
||||
, path ? null
|
||||
, max-workers ? null
|
||||
, keep-going ? null
|
||||
}:
|
||||
|
||||
# TODO: add assert statements
|
||||
@ -105,26 +107,23 @@ let
|
||||
% nix-shell maintainers/scripts/update.nix --argstr path gnome3
|
||||
|
||||
to run update script for all package under an attribute path.
|
||||
|
||||
You can also add
|
||||
|
||||
--argstr max-workers 8
|
||||
|
||||
to increase the number of jobs in parallel, or
|
||||
|
||||
--argstr keep-going true
|
||||
|
||||
to continue running when a single update fails.
|
||||
'';
|
||||
|
||||
runUpdateScript = package: ''
|
||||
echo -ne " - ${package.name}: UPDATING ..."\\r
|
||||
${package.updateScript} &> ${(builtins.parseDrvName package.name).name}.log
|
||||
CODE=$?
|
||||
if [ "$CODE" != "0" ]; then
|
||||
echo " - ${package.name}: ERROR "
|
||||
echo ""
|
||||
echo "--- SHOWING ERROR LOG FOR ${package.name} ----------------------"
|
||||
echo ""
|
||||
cat ${(builtins.parseDrvName package.name).name}.log
|
||||
echo ""
|
||||
echo "--- SHOWING ERROR LOG FOR ${package.name} ----------------------"
|
||||
exit $CODE
|
||||
else
|
||||
rm ${(builtins.parseDrvName package.name).name}.log
|
||||
fi
|
||||
echo " - ${package.name}: DONE. "
|
||||
'';
|
||||
packageData = package: {
|
||||
name = package.name;
|
||||
pname = (builtins.parseDrvName package.name).name;
|
||||
updateScript = pkgs.lib.toList package.updateScript;
|
||||
};
|
||||
|
||||
in pkgs.stdenv.mkDerivation {
|
||||
name = "nixpkgs-update-script";
|
||||
@ -139,21 +138,7 @@ in pkgs.stdenv.mkDerivation {
|
||||
exit 1
|
||||
'';
|
||||
shellHook = ''
|
||||
echo ""
|
||||
echo "Going to be running update for following packages:"
|
||||
echo "${builtins.concatStringsSep "\n" (map (x: " - ${x.name}") packages)}"
|
||||
echo ""
|
||||
read -n1 -r -p "Press space to continue..." confirm
|
||||
if [ "$confirm" = "" ]; then
|
||||
echo ""
|
||||
echo "Running update for:"
|
||||
${builtins.concatStringsSep "\n" (map runUpdateScript packages)}
|
||||
echo ""
|
||||
echo "Packages updated!"
|
||||
exit 0
|
||||
else
|
||||
echo "Aborting!"
|
||||
exit 1
|
||||
fi
|
||||
unset shellHook # do not contaminate nested shells
|
||||
exec ${pkgs.python3.interpreter} ${./update.py} ${pkgs.writeText "packages.json" (builtins.toJSON (map packageData packages))}${pkgs.lib.optionalString (max-workers != null) " --max-workers=${max-workers}"}${pkgs.lib.optionalString (keep-going == "true") " --keep-going"}
|
||||
'';
|
||||
}
|
||||
|
79
maintainers/scripts/update.py
Normal file
79
maintainers/scripts/update.py
Normal file
@ -0,0 +1,79 @@
|
||||
import argparse
|
||||
import concurrent.futures
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
updates = {}
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
def run_update_script(package):
|
||||
eprint(f" - {package['name']}: UPDATING ...")
|
||||
|
||||
subprocess.run(package['updateScript'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=True)
|
||||
|
||||
|
||||
def main(max_workers, keep_going, packages):
|
||||
with open(sys.argv[1]) as f:
|
||||
packages = json.load(f)
|
||||
|
||||
eprint()
|
||||
eprint('Going to be running update for following packages:')
|
||||
for package in packages:
|
||||
eprint(f" - {package['name']}")
|
||||
eprint()
|
||||
|
||||
confirm = input('Press Enter key to continue...')
|
||||
if confirm == '':
|
||||
eprint()
|
||||
eprint('Running update for:')
|
||||
|
||||
with concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) as executor:
|
||||
for package in packages:
|
||||
updates[executor.submit(run_update_script, package)] = package
|
||||
|
||||
for future in concurrent.futures.as_completed(updates):
|
||||
package = updates[future]
|
||||
|
||||
try:
|
||||
future.result()
|
||||
eprint(f" - {package['name']}: DONE.")
|
||||
except subprocess.CalledProcessError as e:
|
||||
eprint(f" - {package['name']}: ERROR")
|
||||
eprint()
|
||||
eprint(f"--- SHOWING ERROR LOG FOR {package['name']} ----------------------")
|
||||
eprint()
|
||||
eprint(e.stdout.decode('utf-8'))
|
||||
with open(f"{package['pname']}.log", 'wb') as f:
|
||||
f.write(e.stdout)
|
||||
eprint()
|
||||
eprint(f"--- SHOWING ERROR LOG FOR {package['name']} ----------------------")
|
||||
|
||||
if not keep_going:
|
||||
sys.exit(1)
|
||||
|
||||
eprint()
|
||||
eprint('Packages updated!')
|
||||
sys.exit()
|
||||
else:
|
||||
eprint('Aborting!')
|
||||
sys.exit(130)
|
||||
|
||||
parser = argparse.ArgumentParser(description='Update packages')
|
||||
parser.add_argument('--max-workers', '-j', dest='max_workers', type=int, help='Number of updates to run concurrently', nargs='?', default=4)
|
||||
parser.add_argument('--keep-going', '-k', dest='keep_going', action='store_true', help='Do not stop after first failure')
|
||||
parser.add_argument('packages', help='JSON file containing the list of package names and their update scripts')
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
main(args.max_workers, args.keep_going, args.packages)
|
||||
except (KeyboardInterrupt, SystemExit) as e:
|
||||
for update in updates:
|
||||
update.cancel()
|
||||
|
||||
sys.exit(e.code if isinstance(e, SystemExit) else 130)
|
@ -4,7 +4,7 @@ all: manual-combined.xml format
|
||||
.PHONY: debug
|
||||
debug: generated manual-combined.xml
|
||||
|
||||
manual-combined.xml: generated *.xml
|
||||
manual-combined.xml: generated *.xml **/*.xml
|
||||
rm -f ./manual-combined.xml
|
||||
nix-shell --packages xmloscopy \
|
||||
--run "xmloscopy --docbook5 ./manual.xml ./manual-combined.xml"
|
||||
|
@ -52,4 +52,8 @@ $ ping -c1 10.233.4.2
|
||||
networking.networkmanager.unmanaged = [ "interface-name:ve-*" ];
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You may need to restart your system for the changes to take effect.
|
||||
</para>
|
||||
</section>
|
||||
|
@ -15,7 +15,7 @@ containers.database =
|
||||
{ config =
|
||||
{ config, pkgs, ... }:
|
||||
{ <xref linkend="opt-services.postgresql.enable"/> = true;
|
||||
<xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql96;
|
||||
<xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql_9_6;
|
||||
};
|
||||
};
|
||||
</programlisting>
|
||||
|
@ -31,7 +31,7 @@ $ cd nixpkgs
|
||||
<para>
|
||||
The second possibility is to add the package outside of the Nixpkgs tree. For
|
||||
instance, here is how you specify a build of the
|
||||
<link xlink:href="http://www.gnu.org/software/hello/">GNU Hello</link>
|
||||
<link xlink:href="https://www.gnu.org/software/hello/">GNU Hello</link>
|
||||
package directly in <filename>configuration.nix</filename>:
|
||||
<programlisting>
|
||||
<xref linkend="opt-environment.systemPackages"/> =
|
||||
|
@ -197,10 +197,10 @@ swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
|
||||
pkgs.emacs
|
||||
];
|
||||
|
||||
<xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql90;
|
||||
<xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql_10;
|
||||
</programlisting>
|
||||
The latter option definition changes the default PostgreSQL package used
|
||||
by NixOS’s PostgreSQL service to 9.0. For more information on packages,
|
||||
by NixOS’s PostgreSQL service to 10.x. For more information on packages,
|
||||
including how to add new ones, see <xref linkend="sec-custom-packages"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
@ -22,5 +22,6 @@
|
||||
<xi:include href="networking.xml" />
|
||||
<xi:include href="linux-kernel.xml" />
|
||||
<xi:include href="../generated/modules.xml" xpointer="xpointer(//section[@id='modules']/*)" />
|
||||
<xi:include href="profiles.xml" />
|
||||
<!-- Apache; libvirtd virtualisation -->
|
||||
</part>
|
||||
|
@ -34,13 +34,4 @@
|
||||
Similarly, UDP port ranges can be opened through
|
||||
<xref linkend="opt-networking.firewall.allowedUDPPortRanges"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Also of interest is
|
||||
<programlisting>
|
||||
<xref linkend="opt-networking.firewall.allowPing"/> = true;
|
||||
</programlisting>
|
||||
to allow the machine to respond to ping requests. (ICMPv6 pings are always
|
||||
allowed.)
|
||||
</para>
|
||||
</section>
|
||||
|
@ -84,18 +84,17 @@ nixpkgs.config.packageOverrides = pkgs:
|
||||
allowImportFromDerivation = true;
|
||||
};
|
||||
]]></screen>
|
||||
|
||||
You can edit the config with this snippet (by default <command>make menuconfig</command> won't work
|
||||
out of the box on nixos):
|
||||
<screen><![CDATA[
|
||||
You can edit the config with this snippet (by default <command>make
|
||||
menuconfig</command> won't work out of the box on nixos):
|
||||
<screen><![CDATA[
|
||||
nix-shell -E 'with import <nixpkgs> {}; kernelToOverride.overrideAttrs (o: {nativeBuildInputs=o.nativeBuildInputs ++ [ pkgconfig ncurses ];})'
|
||||
]]></screen>
|
||||
|
||||
|
||||
or you can let nixpkgs generate the configuration.
|
||||
Nixpkgs generates it via answering the interactive kernel utility <command>make config</command>.
|
||||
The answers depend on parameters passed to <filename>pkgs/os-specific/linux/kernel/generic.nix</filename>
|
||||
(which you can influence by overriding <literal>extraConfig, autoModules, modDirVersion, preferBuiltin, extraConfig</literal>).
|
||||
or you can let nixpkgs generate the configuration. Nixpkgs generates it via
|
||||
answering the interactive kernel utility <command>make config</command>. The
|
||||
answers depend on parameters passed to
|
||||
<filename>pkgs/os-specific/linux/kernel/generic.nix</filename> (which you
|
||||
can influence by overriding <literal>extraConfig, autoModules,
|
||||
modDirVersion, preferBuiltin, extraConfig</literal>).
|
||||
<screen><![CDATA[
|
||||
|
||||
mptcp93.override ({
|
||||
|
@ -113,12 +113,10 @@ $ nixos-option <xref linkend="opt-boot.kernelModules"/>
|
||||
[ "tun" "ipv6" "loop" <replaceable>...</replaceable> ]
|
||||
</screen>
|
||||
Interactive exploration of the configuration is possible using
|
||||
<command
|
||||
xlink:href="https://github.com/edolstra/nix-repl">nix-repl</command>,
|
||||
a read-eval-print loop for Nix expressions. It’s not installed by default;
|
||||
run <literal>nix-env -i nix-repl</literal> to get it. A typical use:
|
||||
<command>nix repl</command>, a read-eval-print loop for Nix expressions.
|
||||
A typical use:
|
||||
<screen>
|
||||
$ nix-repl '<nixpkgs/nixos>'
|
||||
$ nix repl '<nixpkgs/nixos>'
|
||||
|
||||
nix-repl> config.<xref linkend="opt-networking.hostName"/>
|
||||
"mandark"
|
||||
@ -127,4 +125,23 @@ nix-repl> map (x: x.hostName) config.<xref linkend="opt-services.httpd.virtualHo
|
||||
[ "example.org" "example.gov" ]
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
While abstracting your configuration, you may find it useful to generate
|
||||
modules using code, instead of writing files. The example
|
||||
below would have the same effect as importing a file which sets those
|
||||
options.
|
||||
<screen>
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
let netConfig = { hostName }: {
|
||||
networking.hostName = hostName;
|
||||
networking.useDHCP = false;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{ imports = [ (netConfig "nixos.localdomain") ]; }
|
||||
</screen>
|
||||
</para>
|
||||
</section>
|
||||
|
39
nixos/doc/manual/configuration/profiles.xml
Normal file
39
nixos/doc/manual/configuration/profiles.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<chapter 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="ch-profiles">
|
||||
<title>Profiles</title>
|
||||
<para>
|
||||
In some cases, it may be desirable to take advantage of commonly-used,
|
||||
predefined configurations provided by nixpkgs, but different from those that
|
||||
come as default. This is a role fulfilled by NixOS's Profiles, which come as
|
||||
files living in <filename><nixpkgs/nixos/modules/profiles></filename>.
|
||||
That is to say, expected usage is to add them to the imports list of your
|
||||
<filename>/etc/configuration.nix</filename> as such:
|
||||
</para>
|
||||
<programlisting>
|
||||
imports = [
|
||||
<nixpkgs/nixos/modules/profiles/profile-name.nix>
|
||||
];
|
||||
</programlisting>
|
||||
<para>
|
||||
Even if some of these profiles seem only useful in the context of
|
||||
install media, many are actually intended to be used in real installs.
|
||||
</para>
|
||||
<para>
|
||||
What follows is a brief explanation on the purpose and use-case for each
|
||||
profile. Detailing each option configured by each one is out of scope.
|
||||
</para>
|
||||
<xi:include href="profiles/all-hardware.xml" />
|
||||
<xi:include href="profiles/base.xml" />
|
||||
<xi:include href="profiles/clone-config.xml" />
|
||||
<xi:include href="profiles/demo.xml" />
|
||||
<xi:include href="profiles/docker-container.xml" />
|
||||
<xi:include href="profiles/graphical.xml" />
|
||||
<xi:include href="profiles/hardened.xml" />
|
||||
<xi:include href="profiles/headless.xml" />
|
||||
<xi:include href="profiles/installation-device.xml" />
|
||||
<xi:include href="profiles/minimal.xml" />
|
||||
<xi:include href="profiles/qemu-guest.xml" />
|
||||
</chapter>
|
20
nixos/doc/manual/configuration/profiles/all-hardware.xml
Normal file
20
nixos/doc/manual/configuration/profiles/all-hardware.xml
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
<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-profile-all-hardware">
|
||||
<title>All Hardware</title>
|
||||
<para>
|
||||
Enables all hardware supported by NixOS: i.e., all firmware is
|
||||
included, and all devices from which one may boot are enabled in the initrd.
|
||||
Its primary use is in the NixOS installation CDs.
|
||||
</para>
|
||||
<para>
|
||||
The enabled kernel modules include support for SATA and PATA, SCSI
|
||||
(partially), USB, Firewire (untested), Virtio (QEMU, KVM, etc.), VMware, and
|
||||
Hyper-V. Additionally, <xref linkend="opt-hardware.enableAllFirmware"/> is
|
||||
enabled, and the firmware for the ZyDAS ZD1211 chipset is specifically
|
||||
installed.
|
||||
</para>
|
||||
</section>
|
15
nixos/doc/manual/configuration/profiles/base.xml
Normal file
15
nixos/doc/manual/configuration/profiles/base.xml
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
<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-profile-base">
|
||||
<title>Base</title>
|
||||
<para>
|
||||
Defines the software packages included in the "minimal"
|
||||
installation CD. It installs several utilities useful in a simple recovery or
|
||||
install media, such as a text-mode web browser, and tools for manipulating
|
||||
block devices, networking, hardware diagnostics, and filesystems (with their
|
||||
respective kernel modules).
|
||||
</para>
|
||||
</section>
|
14
nixos/doc/manual/configuration/profiles/clone-config.xml
Normal file
14
nixos/doc/manual/configuration/profiles/clone-config.xml
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
<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-profile-clone-config">
|
||||
<title>Clone Config</title>
|
||||
<para>
|
||||
This profile is used in installer images.
|
||||
It provides an editable configuration.nix that imports all the modules that
|
||||
were also used when creating the image in the first place.
|
||||
As a result it allows users to edit and rebuild the live-system.
|
||||
</para>
|
||||
</section>
|
13
nixos/doc/manual/configuration/profiles/demo.xml
Normal file
13
nixos/doc/manual/configuration/profiles/demo.xml
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
<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-profile-demo">
|
||||
<title>Demo</title>
|
||||
<para>
|
||||
This profile just enables a <systemitem class="username">demo</systemitem> user, with password <literal>demo</literal>, uid <literal>1000</literal>, <systemitem class="groupname">wheel</systemitem>
|
||||
group and <link linkend="opt-services.xserver.displayManager.sddm.autoLogin">
|
||||
autologin in the SDDM display manager</link>.
|
||||
</para>
|
||||
</section>
|
15
nixos/doc/manual/configuration/profiles/docker-container.xml
Normal file
15
nixos/doc/manual/configuration/profiles/docker-container.xml
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
<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-profile-docker-container">
|
||||
<title>Docker Container</title>
|
||||
<para>
|
||||
This is the profile from which the Docker images are generated. It prepares a
|
||||
working system by importing the <link linkend="sec-profile-minimal">Minimal</link> and
|
||||
<link linkend="sec-profile-clone-config">Clone Config</link> profiles, and setting appropriate
|
||||
configuration options that are useful inside a container context, like
|
||||
<xref linkend="opt-boot.isContainer"/>.
|
||||
</para>
|
||||
</section>
|
21
nixos/doc/manual/configuration/profiles/graphical.xml
Normal file
21
nixos/doc/manual/configuration/profiles/graphical.xml
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
<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-profile-graphical">
|
||||
<title>Graphical</title>
|
||||
<para>
|
||||
Defines a NixOS configuration with the Plasma 5 desktop. It's used by the
|
||||
graphical installation CD.
|
||||
</para>
|
||||
<para>
|
||||
It sets <xref linkend="opt-services.xserver.enable"/>,
|
||||
<xref linkend="opt-services.xserver.displayManager.sddm.enable"/>,
|
||||
<xref linkend="opt-services.xserver.desktopManager.plasma5.enable"/> (
|
||||
<link linkend="opt-services.xserver.desktopManager.plasma5.enableQt4Support">
|
||||
without Qt4 Support</link>), and
|
||||
<xref linkend="opt-services.xserver.libinput.enable"/> to true. It also
|
||||
includes glxinfo and firefox in the system packages list.
|
||||
</para>
|
||||
</section>
|
22
nixos/doc/manual/configuration/profiles/hardened.xml
Normal file
22
nixos/doc/manual/configuration/profiles/hardened.xml
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
<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-profile-hardened">
|
||||
<title>Hardened</title>
|
||||
<para>
|
||||
A profile with most (vanilla) hardening options enabled by default,
|
||||
potentially at the cost of features and performance.
|
||||
</para>
|
||||
<para>
|
||||
This includes a hardened kernel, and limiting the system information
|
||||
available to processes through the <filename>/sys</filename> and
|
||||
<filename>/proc</filename> filesystems. It also disables the User Namespaces
|
||||
feature of the kernel, which stops Nix from being able to build anything
|
||||
(this particular setting can be overriden via
|
||||
<xref linkend="opt-security.allowUserNamespaces"/>). See the <literal
|
||||
xlink:href="https://github.com/nixos/nixpkgs/tree/master/nixos/modules/profiles/hardened.nix">
|
||||
profile source</literal> for further detail on which settings are altered.
|
||||
</para>
|
||||
</section>
|
18
nixos/doc/manual/configuration/profiles/headless.xml
Normal file
18
nixos/doc/manual/configuration/profiles/headless.xml
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
<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-profile-headless">
|
||||
<title>Headless</title>
|
||||
<para>
|
||||
Common configuration for headless machines (e.g., Amazon EC2 instances).
|
||||
</para>
|
||||
<para>
|
||||
Disables <link linkend="opt-sound.enable">sound</link>,
|
||||
<link linkend="opt-boot.vesa">vesa</link>, serial consoles,
|
||||
<link linkend="opt-systemd.enableEmergencyMode">emergency mode</link>,
|
||||
<link linkend="opt-boot.loader.grub.splashImage">grub splash images</link> and
|
||||
configures the kernel to reboot automatically on panic.
|
||||
</para>
|
||||
</section>
|
@ -0,0 +1,35 @@
|
||||
|
||||
<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-profile-installation-device">
|
||||
<title>Installation Device</title>
|
||||
<para>
|
||||
Provides a basic configuration for installation devices like CDs. This means
|
||||
enabling hardware scans, using the <link linkend="sec-profile-clone-config">
|
||||
Clone Config profile</link> to guarantee
|
||||
<filename>/etc/nixos/configuration.nix</filename> exists (for
|
||||
<command>nixos-rebuild</command> to work), a copy of the Nixpkgs channel
|
||||
snapshot used to create the install media.
|
||||
</para>
|
||||
<para>
|
||||
Additionally, documentation for <link linkend="opt-documentation.enable">
|
||||
Nixpkgs</link> and <link linkend="opt-documentation.nixos.enable">NixOS
|
||||
</link> are forcefully enabled (to override the
|
||||
<link linkend="sec-profile-minimal">Minimal profile</link> preference); the
|
||||
NixOS manual is shown automatically on TTY 8, sudo and udisks are disabled.
|
||||
Autologin is enabled as root.
|
||||
</para>
|
||||
<para>
|
||||
A message is shown to the user to start a display manager if needed,
|
||||
ssh with <xref linkend="opt-services.openssh.permitRootLogin"/> are enabled (but
|
||||
doesn't autostart). WPA Supplicant is also enabled without autostart.
|
||||
</para>
|
||||
<para>
|
||||
Finally, vim is installed, root is set to not have a password, the kernel is
|
||||
made more silent for remote public IP installs, and several settings are
|
||||
tweaked so that the installer has a better chance of succeeding under
|
||||
low-memory environments.
|
||||
</para>
|
||||
</section>
|
17
nixos/doc/manual/configuration/profiles/minimal.xml
Normal file
17
nixos/doc/manual/configuration/profiles/minimal.xml
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
<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-profile-minimal">
|
||||
<title>Minimal</title>
|
||||
<para>
|
||||
This profile defines a small NixOS configuration. It does not contain any
|
||||
graphical stuff. It's a very short file that enables
|
||||
<link linkend="opt-environment.noXlibs">noXlibs</link>, sets
|
||||
<link linkend="opt-i18n.supportedLocales">i18n.supportedLocales</link>
|
||||
to only support the user-selected locale,
|
||||
<link linkend="opt-documentation.enable">disables packages' documentation
|
||||
</link>, and <link linkend="opt-sound.enable">disables sound</link>.
|
||||
</para>
|
||||
</section>
|
16
nixos/doc/manual/configuration/profiles/qemu-guest.xml
Normal file
16
nixos/doc/manual/configuration/profiles/qemu-guest.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<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-profile-qemu-guest">
|
||||
<title>QEMU Guest</title>
|
||||
<para>
|
||||
This profile contains common configuration for virtual machines running under
|
||||
QEMU (using virtio).
|
||||
</para>
|
||||
<para>
|
||||
It makes virtio modules available on the initrd, sets the system time from
|
||||
the hardware clock to work around a bug in qemu-kvm, and
|
||||
<link linkend="opt-security.rngd.enable">enables rngd</link>.
|
||||
</para>
|
||||
</section>
|
@ -90,7 +90,9 @@ let
|
||||
fi
|
||||
${buildPackages.libxslt.bin}/bin/xsltproc \
|
||||
--stringparam revision '${revision}' \
|
||||
-o $out ${./options-to-docbook.xsl} $optionsXML
|
||||
-o intermediate.xml ${./options-to-docbook.xsl} $optionsXML
|
||||
${buildPackages.libxslt.bin}/bin/xsltproc \
|
||||
-o "$out" ${./postprocess-option-descriptions.xsl} intermediate.xml
|
||||
'';
|
||||
|
||||
sources = lib.sourceFilesBySuffices ./. [".xml"];
|
||||
@ -250,7 +252,7 @@ in rec {
|
||||
''; # */
|
||||
|
||||
# Generate the NixOS manual.
|
||||
manual = runCommand "nixos-manual"
|
||||
manualHTML = runCommand "nixos-manual-html"
|
||||
{ inherit sources;
|
||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
||||
meta.description = "The NixOS manual in HTML format";
|
||||
@ -279,6 +281,11 @@ in rec {
|
||||
echo "doc manual $dst" >> $out/nix-support/hydra-build-products
|
||||
''; # */
|
||||
|
||||
# Alias for backward compatibility. TODO(@oxij): remove eventually.
|
||||
manual = manualHTML;
|
||||
|
||||
# Index page of the NixOS manual.
|
||||
manualHTMLIndex = "${manualHTML}/share/doc/nixos/index.html";
|
||||
|
||||
manualEpub = runCommand "nixos-manual-epub"
|
||||
{ inherit sources;
|
||||
|
@ -34,7 +34,7 @@ $ nix-build -A system</screen>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>system.build.manual.manual</varname>
|
||||
<varname>system.build.manual.manualHTML</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
|
37
nixos/doc/manual/development/debugging-nixos-tests.xml
Normal file
37
nixos/doc/manual/development/debugging-nixos-tests.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<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-debugging-nixos-tests">
|
||||
<title>Debugging NixOS tests</title>
|
||||
|
||||
<para>
|
||||
Tests may fail and infrastructure offers access to inspect machine state.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To prevent test from stopping and cleaning up, insert a sleep command:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
$machine->succeed("sleep 84000");
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
As soon as machine starts run as root:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
nix-shell -p socat --run "socat STDIO,raw,echo=0,escape=0x11 UNIX:/tmp/nix-build-vm-test-run-*.drv-0/vm-state-machine/backdoor"
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
You may need to find the correct path, replacing <literal>/tmp</literal>,
|
||||
<literal>*</literal> or <literal>machine</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Press "enter" to open up console and login as "root". After you're done,
|
||||
press "ctrl-q" to exit the console.
|
||||
</para>
|
||||
</section>
|
@ -16,4 +16,5 @@ xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/tests">nixos/test
|
||||
<xi:include href="writing-nixos-tests.xml" />
|
||||
<xi:include href="running-nixos-tests.xml" />
|
||||
<xi:include href="running-nixos-tests-interactively.xml" />
|
||||
<xi:include href="debugging-nixos-tests.xml" />
|
||||
</chapter>
|
||||
|
@ -106,7 +106,7 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<varlistentry xml:id='types.ints.ux'>
|
||||
<term>
|
||||
<varname>types.ints.{u8, u16, u32}</varname>
|
||||
</term>
|
||||
@ -131,6 +131,17 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>types.port</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A port number. This type is an alias to
|
||||
<link linkend='types.ints.ux'><varname>types.ints.u16</varname></link>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
|
@ -19,6 +19,7 @@ starting VDE switch for network 1
|
||||
> startAll
|
||||
> testScript
|
||||
> $machine->succeed("touch /tmp/foo")
|
||||
> print($machine->succeed("pwd")) # Show stdout of command
|
||||
</screen>
|
||||
The function <command>testScript</command> executes the entire test script
|
||||
and drops you back into the test driver command line upon its completion.
|
||||
@ -33,8 +34,11 @@ $ nix-build nixos/tests/login.nix -A driver
|
||||
$ ./result/bin/nixos-run-vms
|
||||
</screen>
|
||||
The script <command>nixos-run-vms</command> starts the virtual machines
|
||||
defined by test. The root file system of the VMs is created on the fly and
|
||||
kept across VM restarts in
|
||||
<filename>./</filename><varname>hostname</varname><filename>.qcow2</filename>.
|
||||
defined by test.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The machine state is kept across VM restarts in
|
||||
<filename>/tmp/vm-state-</filename><varname>machinename</varname>.
|
||||
</para>
|
||||
</section>
|
||||
|
@ -108,7 +108,7 @@ xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/virtualis
|
||||
<programlisting>
|
||||
$machine->start;
|
||||
$machine->waitForUnit("default.target");
|
||||
$machine->succeed("uname") =~ /Linux/;
|
||||
$machine->succeed("uname") =~ /Linux/ or die;
|
||||
</programlisting>
|
||||
The first line is actually unnecessary; machines are implicitly started when
|
||||
you first execute an action on them (such as <literal>waitForUnit</literal>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user