1
Fork 0
mirror of https://github.com/RGBCube/alejandra synced 2025-07-30 12:07:46 +00:00

Add more real-world tests

Taken from the https://github.com/kamadorueda/rfc-0101/ repository
This commit is contained in:
piegames 2023-03-24 16:07:42 +01:00 committed by Kevin Amado
parent ae019014d0
commit b9473ee5ac
18 changed files with 4136 additions and 0 deletions

View file

@ -0,0 +1,456 @@
{ lib }:
rec {
## Simple (higher order) functions
/* The identity function
For when you need a function that does nothing.
Type: id :: a -> a
*/
id =
# The value to return
x: x;
/* The constant function
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 =
# Value to return
x:
# Value to ignore
y: x;
/* Pipes a value through a list of functions, left to right.
Type: pipe :: a -> [<functions>] -> <return type of last function>
Example:
pipe 2 [
(x: x + 2) # 2 + 2 = 4
(x: x * 2) # 4 * 2 = 8
]
=> 8
# ideal to do text transformations
pipe [ "a/b" "a/c" ] [
# create the cp command
(map (file: ''cp "${src}/${file}" $out\n''))
# concatenate all commands into one string
lib.concatStrings
# make that string into a nix derivation
(pkgs.runCommand "copy-to-out" {})
]
=> <drv which copies all files to $out>
The output type of each function has to be the input type
of the next function, and the last function returns the
final value.
*/
pipe = val: functions:
let reverseApply = x: f: f x;
in builtins.foldl' reverseApply val functions;
# note please dont add a function like `compose = flip pipe`.
# This would confuse users, because the order of the functions
# in the list is not clear. With pipe, its obvious that it
# goes first-to-last. With `compose`, not so much.
## Named versions corresponding to some builtin operators.
/* 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 */
or = x: y: x || y;
/* boolean and */
and = x: y: x && y;
/* bitwise and */
bitAnd = builtins.bitAnd
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));
/* bitwise xor */
bitXor = builtins.bitXor
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.
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 =
# 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 the supplied argument is non-null.
Example:
mapNullable (x: x+1) null
=> null
mapNullable (x: x+1) 22
=> 23
*/
mapNullable =
# Function to call
f:
# Argument to check for null before passing it to `f`
a: if a == null then a else f a;
# Pull in some builtins not included elsewhere.
inherit (builtins)
pathExists readFile isBool
isInt isFloat add sub lessThan
seq deepSeq genericClosure;
## nixpkgs version strings
/* Returns the current full nixpkgs version number. */
version = release + versionSuffix;
/* Returns the current nixpkgs release number as string. */
release = lib.strings.fileContents ../.version;
/* 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 = "Quokka";
/* 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.pathIsGitRepo 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;
/* 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 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
Example:
mod 11 10
=> 1
mod 1 10
=> 1
*/
mod = base: int: base - (int * (builtins.div base int));
## Comparisons
/* C-style comparisons
a < b, compare a b => -1
a == b, compare a b => 0
a > b, compare a b => 1
*/
compare = a: b:
if a < b
then -1
else if a > b
then 1
else 0;
/* Split type into two subtypes by predicate `p`, take all elements
of the first subtype to be less than all the elements of the
second subtype, compare elements of a single subtype with `yes`
and `no` respectively.
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
cmp "fooa" "fooz" => -1
cmp "f" "a" => 1
cmp "fooa" "a" => -1
# while
compare "fooa" "a" => 1
*/
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.
Type :: path -> any
*/
importJSON = path:
builtins.fromJSON (builtins.readFile path);
/* Reads a TOML file.
Type :: path -> any
*/
importTOML = path:
builtins.fromTOML (builtins.readFile path);
## 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.
#
# Usage:
# {
# foo = lib.warn "foo is deprecated" oldFoo;
# bar = lib.warnIf (bar == "") "Empty bar is deprecated" bar;
# }
#
# TODO: figure out a clever way to integrate location information from
# something like __unsafeGetAttrPos.
/*
Print a warning before returning the second argument. This function behaves
like `builtins.trace`, but requires a string message and formats it as a
warning, including the `warning: ` prefix.
To get a call stack trace and abort evaluation, set the environment variable
`NIX_ABORT_ON_WARN=true` and set the Nix options `--option pure-eval false --show-trace`
Type: string -> a -> a
*/
warn =
if lib.elem (builtins.getEnv "NIX_ABORT_ON_WARN") ["1" "true" "yes"]
then msg: builtins.trace "warning: ${msg}" (abort "NIX_ABORT_ON_WARN=true; warnings are treated as unrecoverable errors.")
else msg: builtins.trace "warning: ${msg}";
/*
Like warn, but only warn when the first argument is `true`.
Type: bool -> string -> a -> a
*/
warnIf = cond: msg: if cond then warn msg else id;
/*
Like the `assert b; e` expression, but with a custom error message and
without the semicolon.
If true, return the identity function, `r: r`.
If false, throw the error message.
Calls can be juxtaposed using function application, as `(r: r) a = a`, so
`(r: r) (r: r) a = a`, and so forth.
Type: bool -> string -> a -> a
Example:
throwIfNot (lib.isList overlays) "The overlays argument to nixpkgs must be a list."
lib.foldr (x: throwIfNot (lib.isFunction x) "All overlays passed to nixpkgs must be functions.") (r: r) overlays
pkgs
*/
throwIfNot = cond: msg: if cond then x: x else throw msg;
/* Check if the elements in a list are valid values from a enum, returning the identity function, or throwing an error message otherwise.
Example:
let colorVariants = ["bright" "dark" "black"]
in checkListOfEnum "color variants" [ "standard" "light" "dark" ] colorVariants;
=>
error: color variants: bright, black unexpected; valid ones: standard, light, dark
Type: String -> List ComparableVal -> List ComparableVal -> a -> a
*/
checkListOfEnum = msg: valid: given:
let
unexpected = lib.subtractLists valid given;
in
lib.throwIfNot (unexpected == [])
"${msg}: ${builtins.concatStringsSep ", " (builtins.map builtins.toString unexpected)} unexpected; valid ones: ${builtins.concatStringsSep ", " (builtins.map builtins.toString valid)}";
info = msg: builtins.trace "INFO: ${msg}";
showWarnings = warnings: res: lib.foldr (w: x: warn w x) res warnings;
## Function annotations
/* Add metadata about expected function arguments to a function.
The metadata should match the format given by
builtins.functionArgs, i.e. a set from expected argument to a bool
representing whether that argument has a default or not.
setFunctionArgs : (a b) Map String Bool (a b)
This function is necessary because you can't dynamically create a
function of the { a, b ? foo, ... }: format, but some facilities
like callPackage expect to be able to query expected arguments.
*/
setFunctionArgs = f: args:
{ # TODO: Should we add call-time "type" checking like built in?
__functor = self: f;
__functionArgs = args;
};
/* Extract the expected function arguments from a function.
This works both with nix-native { a, b ? foo, ... }: style
functions and functions with args set with 'setFunctionArgs'. It
has the same return type and semantics as builtins.functionArgs.
setFunctionArgs : (a b) Map String Bool.
*/
functionArgs = f:
if f ? __functor
then f.__functionArgs or (lib.functionArgs (f.__functor f))
else builtins.functionArgs f;
/* Check whether something is a function or something
annotated with function args.
*/
isFunction = f: builtins.isFunction f ||
(f ? __functor && isFunction (f.__functor f));
/* Convert the given positive integer to a string of its hexadecimal
representation. For example:
toHexString 0 => "0"
toHexString 16 => "10"
toHexString 250 => "FA"
*/
toHexString = i:
let
toHexDigit = d:
if d < 10
then toString d
else
{
"10" = "A";
"11" = "B";
"12" = "C";
"13" = "D";
"14" = "E";
"15" = "F";
}.${toString d};
in
lib.concatMapStrings toHexDigit (toBaseDigits 16 i);
/* `toBaseDigits base i` converts the positive integer i to a list of its
digits in the given base. For example:
toBaseDigits 10 123 => [ 1 2 3 ]
toBaseDigits 2 6 => [ 1 1 0 ]
toBaseDigits 16 250 => [ 15 10 ]
*/
toBaseDigits = base: i:
let
go = i:
if i < base
then [i]
else
let
r = i - ((i / base) * base);
q = (i - r) / base;
in
[r] ++ go q;
in
assert (base >= 2);
assert (i >= 0);
lib.reverseList (go i);
}

View file

@ -0,0 +1,539 @@
{lib}: rec {
## Simple (higher order) functions
/*
The identity function
For when you need a function that does nothing.
Type: id :: a -> a
*/
id =
# The value to return
x: x;
/*
The constant function
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 =
# Value to return
x:
# Value to ignore
y: x;
/*
Pipes a value through a list of functions, left to right.
Type: pipe :: a -> [<functions>] -> <return type of last function>
Example:
pipe 2 [
(x: x + 2) # 2 + 2 = 4
(x: x * 2) # 4 * 2 = 8
]
=> 8
# ideal to do text transformations
pipe [ "a/b" "a/c" ] [
# create the cp command
(map (file: ''cp "${src}/${file}" $out\n''))
# concatenate all commands into one string
lib.concatStrings
# make that string into a nix derivation
(pkgs.runCommand "copy-to-out" {})
]
=> <drv which copies all files to $out>
The output type of each function has to be the input type
of the next function, and the last function returns the
final value.
*/
pipe = val: functions: let
reverseApply = x: f: f x;
in
builtins.foldl' reverseApply val functions;
# note please dont add a function like `compose = flip pipe`.
# This would confuse users, because the order of the functions
# in the list is not clear. With pipe, its obvious that it
# goes first-to-last. With `compose`, not so much.
## Named versions corresponding to some builtin operators.
/*
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
*/
or = x: y: x || y;
/*
boolean and
*/
and = x: y: x && y;
/*
bitwise and
*/
bitAnd =
builtins.bitAnd
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));
/*
bitwise xor
*/
bitXor =
builtins.bitXor
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.
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 =
# 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 the supplied argument is non-null.
Example:
mapNullable (x: x+1) null
=> null
mapNullable (x: x+1) 22
=> 23
*/
mapNullable =
# Function to call
f:
# Argument to check for null before passing it to `f`
a:
if a == null
then a
else f a;
# Pull in some builtins not included elsewhere.
inherit
(builtins)
pathExists
readFile
isBool
isInt
isFloat
add
sub
lessThan
seq
deepSeq
genericClosure
;
## nixpkgs version strings
/*
Returns the current full nixpkgs version number.
*/
version = release + versionSuffix;
/*
Returns the current nixpkgs release number as string.
*/
release = lib.strings.fileContents ../.version;
/*
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 = "Quokka";
/*
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.pathIsGitRepo 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;
/*
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 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
Example:
mod 11 10
=> 1
mod 1 10
=> 1
*/
mod = base: int: base - (int * (builtins.div base int));
## Comparisons
/*
C-style comparisons
a < b, compare a b => -1
a == b, compare a b => 0
a > b, compare a b => 1
*/
compare = a: b:
if a < b
then -1
else if a > b
then 1
else 0;
/*
Split type into two subtypes by predicate `p`, take all elements
of the first subtype to be less than all the elements of the
second subtype, compare elements of a single subtype with `yes`
and `no` respectively.
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
cmp "fooa" "fooz" => -1
cmp "f" "a" => 1
cmp "fooa" "a" => -1
# while
compare "fooa" "a" => 1
*/
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.
Type :: path -> any
*/
importJSON = path:
builtins.fromJSON (builtins.readFile path);
/*
Reads a TOML file.
Type :: path -> any
*/
importTOML = path:
builtins.fromTOML (builtins.readFile path);
## 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.
#
# Usage:
# {
# foo = lib.warn "foo is deprecated" oldFoo;
# bar = lib.warnIf (bar == "") "Empty bar is deprecated" bar;
# }
#
# TODO: figure out a clever way to integrate location information from
# something like __unsafeGetAttrPos.
/*
Print a warning before returning the second argument. This function behaves
like `builtins.trace`, but requires a string message and formats it as a
warning, including the `warning: ` prefix.
To get a call stack trace and abort evaluation, set the environment variable
`NIX_ABORT_ON_WARN=true` and set the Nix options `--option pure-eval false --show-trace`
Type: string -> a -> a
*/
warn =
if lib.elem (builtins.getEnv "NIX_ABORT_ON_WARN") ["1" "true" "yes"]
then msg: builtins.trace "warning: ${msg}" (abort "NIX_ABORT_ON_WARN=true; warnings are treated as unrecoverable errors.")
else msg: builtins.trace "warning: ${msg}";
/*
Like warn, but only warn when the first argument is `true`.
Type: bool -> string -> a -> a
*/
warnIf = cond: msg:
if cond
then warn msg
else id;
/*
Like the `assert b; e` expression, but with a custom error message and
without the semicolon.
If true, return the identity function, `r: r`.
If false, throw the error message.
Calls can be juxtaposed using function application, as `(r: r) a = a`, so
`(r: r) (r: r) a = a`, and so forth.
Type: bool -> string -> a -> a
Example:
throwIfNot (lib.isList overlays) "The overlays argument to nixpkgs must be a list."
lib.foldr (x: throwIfNot (lib.isFunction x) "All overlays passed to nixpkgs must be functions.") (r: r) overlays
pkgs
*/
throwIfNot = cond: msg:
if cond
then x: x
else throw msg;
/*
Check if the elements in a list are valid values from a enum, returning the identity function, or throwing an error message otherwise.
Example:
let colorVariants = ["bright" "dark" "black"]
in checkListOfEnum "color variants" [ "standard" "light" "dark" ] colorVariants;
=>
error: color variants: bright, black unexpected; valid ones: standard, light, dark
Type: String -> List ComparableVal -> List ComparableVal -> a -> a
*/
checkListOfEnum = msg: valid: given: let
unexpected = lib.subtractLists valid given;
in
lib.throwIfNot (unexpected == [])
"${msg}: ${builtins.concatStringsSep ", " (builtins.map builtins.toString unexpected)} unexpected; valid ones: ${builtins.concatStringsSep ", " (builtins.map builtins.toString valid)}";
info = msg: builtins.trace "INFO: ${msg}";
showWarnings = warnings: res: lib.foldr (w: x: warn w x) res warnings;
## Function annotations
/*
Add metadata about expected function arguments to a function.
The metadata should match the format given by
builtins.functionArgs, i.e. a set from expected argument to a bool
representing whether that argument has a default or not.
setFunctionArgs : (a b) Map String Bool (a b)
This function is necessary because you can't dynamically create a
function of the { a, b ? foo, ... }: format, but some facilities
like callPackage expect to be able to query expected arguments.
*/
setFunctionArgs = f: args: {
# TODO: Should we add call-time "type" checking like built in?
__functor = self: f;
__functionArgs = args;
};
/*
Extract the expected function arguments from a function.
This works both with nix-native { a, b ? foo, ... }: style
functions and functions with args set with 'setFunctionArgs'. It
has the same return type and semantics as builtins.functionArgs.
setFunctionArgs : (a b) Map String Bool.
*/
functionArgs = f:
if f ? __functor
then f.__functionArgs or (lib.functionArgs (f.__functor f))
else builtins.functionArgs f;
/*
Check whether something is a function or something
annotated with function args.
*/
isFunction = f:
builtins.isFunction f
|| (f ? __functor && isFunction (f.__functor f));
/*
Convert the given positive integer to a string of its hexadecimal
representation. For example:
toHexString 0 => "0"
toHexString 16 => "10"
toHexString 250 => "FA"
*/
toHexString = i: let
toHexDigit = d:
if d < 10
then toString d
else
{
"10" = "A";
"11" = "B";
"12" = "C";
"13" = "D";
"14" = "E";
"15" = "F";
}
.${toString d};
in
lib.concatMapStrings toHexDigit (toBaseDigits 16 i);
/*
`toBaseDigits base i` converts the positive integer i to a list of its
digits in the given base. For example:
toBaseDigits 10 123 => [ 1 2 3 ]
toBaseDigits 2 6 => [ 1 1 0 ]
toBaseDigits 16 250 => [ 15 10 ]
*/
toBaseDigits = base: i: let
go = i:
if i < base
then [i]
else let
r = i - ((i / base) * base);
q = (i - r) / base;
in
[r] ++ go q;
in
assert (base >= 2);
assert (i >= 0);
lib.reverseList (go i);
}

View file

@ -0,0 +1,350 @@
{ config, lib, pkgs, ... }:
with lib;
let
inherit (config.boot) kernelPatches;
inherit (config.boot.kernel) features randstructSeed;
inherit (config.boot.kernelPackages) kernel;
kernelModulesConf = pkgs.writeText "nixos.conf"
''
${concatStringsSep "\n" config.boot.kernelModules}
'';
in
{
###### interface
options = {
boot.kernel.features = mkOption {
default = {};
example = literalExpression "{ debug = true; }";
internal = true;
description = ''
This option allows to enable or disable certain kernel features.
It's not API, because it's about kernel feature sets, that
make sense for specific use cases. Mostly along with programs,
which would have separate nixos options.
`grep features pkgs/os-specific/linux/kernel/common-config.nix`
'';
};
boot.kernelPackages = mkOption {
default = pkgs.linuxPackages;
type = types.unspecified // { merge = mergeEqualOption; };
apply = kernelPackages: kernelPackages.extend (self: super: {
kernel = super.kernel.override (originalArgs: {
inherit randstructSeed;
kernelPatches = (originalArgs.kernelPatches or []) ++ kernelPatches;
features = lib.recursiveUpdate super.kernel.features features;
});
});
# We don't want to evaluate all of linuxPackages for the manual
# - some of it might not even evaluate correctly.
defaultText = literalExpression "pkgs.linuxPackages";
example = literalExpression "pkgs.linuxKernel.packages.linux_5_10";
description = ''
This option allows you to override the Linux kernel used by
NixOS. Since things like external kernel module packages are
tied to the kernel you're using, it also overrides those.
This option is a function that takes Nixpkgs as an argument
(as a convenience), and returns an attribute set containing at
the very least an attribute <varname>kernel</varname>.
Additional attributes may be needed depending on your
configuration. For instance, if you use the NVIDIA X driver,
then it also needs to contain an attribute
<varname>nvidia_x11</varname>.
'';
};
boot.kernelPatches = mkOption {
type = types.listOf types.attrs;
default = [];
example = literalExpression "[ pkgs.kernelPatches.ubuntu_fan_4_4 ]";
description = "A list of additional patches to apply to the kernel.";
};
boot.kernel.randstructSeed = mkOption {
type = types.str;
default = "";
example = "my secret seed";
description = ''
Provides a custom seed for the <varname>RANDSTRUCT</varname> security
option of the Linux kernel. Note that <varname>RANDSTRUCT</varname> is
only enabled in NixOS hardened kernels. Using a custom seed requires
building the kernel and dependent packages locally, since this
customization happens at build time.
'';
};
boot.kernelParams = mkOption {
type = types.listOf (types.strMatching ''([^"[:space:]]|"[^"]*")+'' // {
name = "kernelParam";
description = "string, with spaces inside double quotes";
});
default = [ ];
description = "Parameters added to the kernel command line.";
};
boot.consoleLogLevel = mkOption {
type = types.int;
default = 4;
description = ''
The kernel console <literal>loglevel</literal>. All Kernel Messages with a log level smaller
than this setting will be printed to the console.
'';
};
boot.vesa = mkOption {
type = types.bool;
default = false;
description = ''
(Deprecated) This option, if set, activates the VESA 800x600 video
mode on boot and disables kernel modesetting. It is equivalent to
specifying <literal>[ "vga=0x317" "nomodeset" ]</literal> in the
<option>boot.kernelParams</option> option. This option is
deprecated as of 2020: Xorg now works better with modesetting, and
you might want a different VESA vga setting, anyway.
'';
};
boot.extraModulePackages = mkOption {
type = types.listOf types.package;
default = [];
example = literalExpression "[ config.boot.kernelPackages.nvidia_x11 ]";
description = "A list of additional packages supplying kernel modules.";
};
boot.kernelModules = mkOption {
type = types.listOf types.str;
default = [];
description = ''
The set of kernel modules to be loaded in the second stage of
the boot process. Note that modules that are needed to
mount the root file system should be added to
<option>boot.initrd.availableKernelModules</option> or
<option>boot.initrd.kernelModules</option>.
'';
};
boot.initrd.availableKernelModules = mkOption {
type = types.listOf types.str;
default = [];
example = [ "sata_nv" "ext3" ];
description = ''
The set of kernel modules in the initial ramdisk used during the
boot process. This set must include all modules necessary for
mounting the root device. That is, it should include modules
for the physical device (e.g., SCSI drivers) and for the file
system (e.g., ext3). The set specified here is automatically
closed under the module dependency relation, i.e., all
dependencies of the modules list here are included
automatically. The modules listed here are available in the
initrd, but are only loaded on demand (e.g., the ext3 module is
loaded automatically when an ext3 filesystem is mounted, and
modules for PCI devices are loaded when they match the PCI ID
of a device in your system). To force a module to be loaded,
include it in <option>boot.initrd.kernelModules</option>.
'';
};
boot.initrd.kernelModules = mkOption {
type = types.listOf types.str;
default = [];
description = "List of modules that are always loaded by the initrd.";
};
boot.initrd.includeDefaultModules = mkOption {
type = types.bool;
default = true;
description = ''
This option, if set, adds a collection of default kernel modules
to <option>boot.initrd.availableKernelModules</option> and
<option>boot.initrd.kernelModules</option>.
'';
};
system.modulesTree = mkOption {
type = types.listOf types.path;
internal = true;
default = [];
description = ''
Tree of kernel modules. This includes the kernel, plus modules
built outside of the kernel. Combine these into a single tree of
symlinks because modprobe only supports one directory.
'';
# Convert the list of path to only one path.
apply = pkgs.aggregateModules;
};
system.requiredKernelConfig = mkOption {
default = [];
example = literalExpression ''
with config.lib.kernelConfig; [
(isYes "MODULES")
(isEnabled "FB_CON_DECOR")
(isEnabled "BLK_DEV_INITRD")
]
'';
internal = true;
type = types.listOf types.attrs;
description = ''
This option allows modules to specify the kernel config options that
must be set (or unset) for the module to work. Please use the
lib.kernelConfig functions to build list elements.
'';
};
};
###### implementation
config = mkMerge
[ (mkIf config.boot.initrd.enable {
boot.initrd.availableKernelModules =
optionals config.boot.initrd.includeDefaultModules ([
# Note: most of these (especially the SATA/PATA modules)
# shouldn't be included by default since nixos-generate-config
# detects them, but I'm keeping them for now for backwards
# compatibility.
# Some SATA/PATA stuff.
"ahci"
"sata_nv"
"sata_via"
"sata_sis"
"sata_uli"
"ata_piix"
"pata_marvell"
# Standard SCSI stuff.
"sd_mod"
"sr_mod"
# SD cards and internal eMMC drives.
"mmc_block"
# Support USB keyboards, in case the boot fails and we only have
# a USB keyboard, or for LUKS passphrase prompt.
"uhci_hcd"
"ehci_hcd"
"ehci_pci"
"ohci_hcd"
"ohci_pci"
"xhci_hcd"
"xhci_pci"
"usbhid"
"hid_generic" "hid_lenovo" "hid_apple" "hid_roccat"
"hid_logitech_hidpp" "hid_logitech_dj" "hid_microsoft"
] ++ optionals pkgs.stdenv.hostPlatform.isx86 [
# Misc. x86 keyboard stuff.
"pcips2" "atkbd" "i8042"
# x86 RTC needed by the stage 2 init script.
"rtc_cmos"
]);
boot.initrd.kernelModules =
optionals config.boot.initrd.includeDefaultModules [
# For LVM.
"dm_mod"
];
})
(mkIf (!config.boot.isContainer) {
system.build = { inherit kernel; };
system.modulesTree = [ kernel ] ++ config.boot.extraModulePackages;
# Implement consoleLogLevel both in early boot and using sysctl
# (so you don't need to reboot to have changes take effect).
boot.kernelParams =
[ "loglevel=${toString config.boot.consoleLogLevel}" ] ++
optionals config.boot.vesa [ "vga=0x317" "nomodeset" ];
boot.kernel.sysctl."kernel.printk" = mkDefault config.boot.consoleLogLevel;
boot.kernelModules = [ "loop" "atkbd" ];
# The Linux kernel >= 2.6.27 provides firmware.
hardware.firmware = [ kernel ];
# Create /etc/modules-load.d/nixos.conf, which is read by
# systemd-modules-load.service to load required kernel modules.
environment.etc =
{ "modules-load.d/nixos.conf".source = kernelModulesConf;
};
systemd.services.systemd-modules-load =
{ wantedBy = [ "multi-user.target" ];
restartTriggers = [ kernelModulesConf ];
serviceConfig =
{ # Ignore failed module loads. Typically some of the
# modules in boot.kernelModules are "nice to have but
# not required" (e.g. acpi-cpufreq), so we don't want to
# barf on those.
SuccessExitStatus = "0 1";
};
};
lib.kernelConfig = {
isYes = option: {
assertion = config: config.isYes option;
message = "CONFIG_${option} is not yes!";
configLine = "CONFIG_${option}=y";
};
isNo = option: {
assertion = config: config.isNo option;
message = "CONFIG_${option} is not no!";
configLine = "CONFIG_${option}=n";
};
isModule = option: {
assertion = config: config.isModule option;
message = "CONFIG_${option} is not built as a module!";
configLine = "CONFIG_${option}=m";
};
### Usually you will just want to use these two
# True if yes or module
isEnabled = option: {
assertion = config: config.isEnabled option;
message = "CONFIG_${option} is not enabled!";
configLine = "CONFIG_${option}=y";
};
# True if no or omitted
isDisabled = option: {
assertion = config: config.isDisabled option;
message = "CONFIG_${option} is not disabled!";
configLine = "CONFIG_${option}=n";
};
};
# The config options that all modules can depend upon
system.requiredKernelConfig = with config.lib.kernelConfig;
[
# !!! Should this really be needed?
(isYes "MODULES")
(isYes "BINFMT_ELF")
] ++ (optional (randstructSeed != "") (isYes "GCC_PLUGIN_RANDSTRUCT"));
# nixpkgs kernels are assumed to have all required features
assertions = if config.boot.kernelPackages.kernel ? features then [] else
let cfg = config.boot.kernelPackages.kernel.config; in map (attrs:
{ assertion = attrs.assertion cfg; inherit (attrs) message; }
) config.system.requiredKernelConfig;
})
];
}

View file

@ -0,0 +1,361 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
inherit (config.boot) kernelPatches;
inherit (config.boot.kernel) features randstructSeed;
inherit (config.boot.kernelPackages) kernel;
kernelModulesConf =
pkgs.writeText "nixos.conf"
''
${concatStringsSep "\n" config.boot.kernelModules}
'';
in {
###### interface
options = {
boot.kernel.features = mkOption {
default = {};
example = literalExpression "{ debug = true; }";
internal = true;
description = ''
This option allows to enable or disable certain kernel features.
It's not API, because it's about kernel feature sets, that
make sense for specific use cases. Mostly along with programs,
which would have separate nixos options.
`grep features pkgs/os-specific/linux/kernel/common-config.nix`
'';
};
boot.kernelPackages = mkOption {
default = pkgs.linuxPackages;
type = types.unspecified // {merge = mergeEqualOption;};
apply = kernelPackages:
kernelPackages.extend (self: super: {
kernel = super.kernel.override (originalArgs: {
inherit randstructSeed;
kernelPatches = (originalArgs.kernelPatches or []) ++ kernelPatches;
features = lib.recursiveUpdate super.kernel.features features;
});
});
# We don't want to evaluate all of linuxPackages for the manual
# - some of it might not even evaluate correctly.
defaultText = literalExpression "pkgs.linuxPackages";
example = literalExpression "pkgs.linuxKernel.packages.linux_5_10";
description = ''
This option allows you to override the Linux kernel used by
NixOS. Since things like external kernel module packages are
tied to the kernel you're using, it also overrides those.
This option is a function that takes Nixpkgs as an argument
(as a convenience), and returns an attribute set containing at
the very least an attribute <varname>kernel</varname>.
Additional attributes may be needed depending on your
configuration. For instance, if you use the NVIDIA X driver,
then it also needs to contain an attribute
<varname>nvidia_x11</varname>.
'';
};
boot.kernelPatches = mkOption {
type = types.listOf types.attrs;
default = [];
example = literalExpression "[ pkgs.kernelPatches.ubuntu_fan_4_4 ]";
description = "A list of additional patches to apply to the kernel.";
};
boot.kernel.randstructSeed = mkOption {
type = types.str;
default = "";
example = "my secret seed";
description = ''
Provides a custom seed for the <varname>RANDSTRUCT</varname> security
option of the Linux kernel. Note that <varname>RANDSTRUCT</varname> is
only enabled in NixOS hardened kernels. Using a custom seed requires
building the kernel and dependent packages locally, since this
customization happens at build time.
'';
};
boot.kernelParams = mkOption {
type = types.listOf (types.strMatching ''([^"[:space:]]|"[^"]*")+''
// {
name = "kernelParam";
description = "string, with spaces inside double quotes";
});
default = [];
description = "Parameters added to the kernel command line.";
};
boot.consoleLogLevel = mkOption {
type = types.int;
default = 4;
description = ''
The kernel console <literal>loglevel</literal>. All Kernel Messages with a log level smaller
than this setting will be printed to the console.
'';
};
boot.vesa = mkOption {
type = types.bool;
default = false;
description = ''
(Deprecated) This option, if set, activates the VESA 800x600 video
mode on boot and disables kernel modesetting. It is equivalent to
specifying <literal>[ "vga=0x317" "nomodeset" ]</literal> in the
<option>boot.kernelParams</option> option. This option is
deprecated as of 2020: Xorg now works better with modesetting, and
you might want a different VESA vga setting, anyway.
'';
};
boot.extraModulePackages = mkOption {
type = types.listOf types.package;
default = [];
example = literalExpression "[ config.boot.kernelPackages.nvidia_x11 ]";
description = "A list of additional packages supplying kernel modules.";
};
boot.kernelModules = mkOption {
type = types.listOf types.str;
default = [];
description = ''
The set of kernel modules to be loaded in the second stage of
the boot process. Note that modules that are needed to
mount the root file system should be added to
<option>boot.initrd.availableKernelModules</option> or
<option>boot.initrd.kernelModules</option>.
'';
};
boot.initrd.availableKernelModules = mkOption {
type = types.listOf types.str;
default = [];
example = ["sata_nv" "ext3"];
description = ''
The set of kernel modules in the initial ramdisk used during the
boot process. This set must include all modules necessary for
mounting the root device. That is, it should include modules
for the physical device (e.g., SCSI drivers) and for the file
system (e.g., ext3). The set specified here is automatically
closed under the module dependency relation, i.e., all
dependencies of the modules list here are included
automatically. The modules listed here are available in the
initrd, but are only loaded on demand (e.g., the ext3 module is
loaded automatically when an ext3 filesystem is mounted, and
modules for PCI devices are loaded when they match the PCI ID
of a device in your system). To force a module to be loaded,
include it in <option>boot.initrd.kernelModules</option>.
'';
};
boot.initrd.kernelModules = mkOption {
type = types.listOf types.str;
default = [];
description = "List of modules that are always loaded by the initrd.";
};
boot.initrd.includeDefaultModules = mkOption {
type = types.bool;
default = true;
description = ''
This option, if set, adds a collection of default kernel modules
to <option>boot.initrd.availableKernelModules</option> and
<option>boot.initrd.kernelModules</option>.
'';
};
system.modulesTree = mkOption {
type = types.listOf types.path;
internal = true;
default = [];
description = ''
Tree of kernel modules. This includes the kernel, plus modules
built outside of the kernel. Combine these into a single tree of
symlinks because modprobe only supports one directory.
'';
# Convert the list of path to only one path.
apply = pkgs.aggregateModules;
};
system.requiredKernelConfig = mkOption {
default = [];
example = literalExpression ''
with config.lib.kernelConfig; [
(isYes "MODULES")
(isEnabled "FB_CON_DECOR")
(isEnabled "BLK_DEV_INITRD")
]
'';
internal = true;
type = types.listOf types.attrs;
description = ''
This option allows modules to specify the kernel config options that
must be set (or unset) for the module to work. Please use the
lib.kernelConfig functions to build list elements.
'';
};
};
###### implementation
config =
mkMerge
[
(mkIf config.boot.initrd.enable {
boot.initrd.availableKernelModules = optionals config.boot.initrd.includeDefaultModules ([
# Note: most of these (especially the SATA/PATA modules)
# shouldn't be included by default since nixos-generate-config
# detects them, but I'm keeping them for now for backwards
# compatibility.
# Some SATA/PATA stuff.
"ahci"
"sata_nv"
"sata_via"
"sata_sis"
"sata_uli"
"ata_piix"
"pata_marvell"
# Standard SCSI stuff.
"sd_mod"
"sr_mod"
# SD cards and internal eMMC drives.
"mmc_block"
# Support USB keyboards, in case the boot fails and we only have
# a USB keyboard, or for LUKS passphrase prompt.
"uhci_hcd"
"ehci_hcd"
"ehci_pci"
"ohci_hcd"
"ohci_pci"
"xhci_hcd"
"xhci_pci"
"usbhid"
"hid_generic"
"hid_lenovo"
"hid_apple"
"hid_roccat"
"hid_logitech_hidpp"
"hid_logitech_dj"
"hid_microsoft"
]
++ optionals pkgs.stdenv.hostPlatform.isx86 [
# Misc. x86 keyboard stuff.
"pcips2"
"atkbd"
"i8042"
# x86 RTC needed by the stage 2 init script.
"rtc_cmos"
]);
boot.initrd.kernelModules = optionals config.boot.initrd.includeDefaultModules [
# For LVM.
"dm_mod"
];
})
(mkIf (!config.boot.isContainer) {
system.build = {inherit kernel;};
system.modulesTree = [kernel] ++ config.boot.extraModulePackages;
# Implement consoleLogLevel both in early boot and using sysctl
# (so you don't need to reboot to have changes take effect).
boot.kernelParams =
["loglevel=${toString config.boot.consoleLogLevel}"]
++ optionals config.boot.vesa ["vga=0x317" "nomodeset"];
boot.kernel.sysctl."kernel.printk" = mkDefault config.boot.consoleLogLevel;
boot.kernelModules = ["loop" "atkbd"];
# The Linux kernel >= 2.6.27 provides firmware.
hardware.firmware = [kernel];
# Create /etc/modules-load.d/nixos.conf, which is read by
# systemd-modules-load.service to load required kernel modules.
environment.etc = {
"modules-load.d/nixos.conf".source = kernelModulesConf;
};
systemd.services.systemd-modules-load = {
wantedBy = ["multi-user.target"];
restartTriggers = [kernelModulesConf];
serviceConfig = {
# Ignore failed module loads. Typically some of the
# modules in boot.kernelModules are "nice to have but
# not required" (e.g. acpi-cpufreq), so we don't want to
# barf on those.
SuccessExitStatus = "0 1";
};
};
lib.kernelConfig = {
isYes = option: {
assertion = config: config.isYes option;
message = "CONFIG_${option} is not yes!";
configLine = "CONFIG_${option}=y";
};
isNo = option: {
assertion = config: config.isNo option;
message = "CONFIG_${option} is not no!";
configLine = "CONFIG_${option}=n";
};
isModule = option: {
assertion = config: config.isModule option;
message = "CONFIG_${option} is not built as a module!";
configLine = "CONFIG_${option}=m";
};
### Usually you will just want to use these two
# True if yes or module
isEnabled = option: {
assertion = config: config.isEnabled option;
message = "CONFIG_${option} is not enabled!";
configLine = "CONFIG_${option}=y";
};
# True if no or omitted
isDisabled = option: {
assertion = config: config.isDisabled option;
message = "CONFIG_${option} is not disabled!";
configLine = "CONFIG_${option}=n";
};
};
# The config options that all modules can depend upon
system.requiredKernelConfig = with config.lib.kernelConfig;
[
# !!! Should this really be needed?
(isYes "MODULES")
(isYes "BINFMT_ELF")
]
++ (optional (randstructSeed != "") (isYes "GCC_PLUGIN_RANDSTRUCT"));
# nixpkgs kernels are assumed to have all required features
assertions =
if config.boot.kernelPackages.kernel ? features
then []
else let
cfg = config.boot.kernelPackages.kernel.config;
in
map (
attrs: {
assertion = attrs.assertion cfg;
inherit (attrs) message;
}
)
config.system.requiredKernelConfig;
})
];
}

View file

@ -0,0 +1,43 @@
{ lib
, stdenv
, fetchurl
, nixos
, testVersion
, testEqualDerivation
, hello
}:
stdenv.mkDerivation rec {
pname = "hello";
version = "2.12";
src = fetchurl {
url = "mirror://gnu/hello/${pname}-${version}.tar.gz";
sha256 = "1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g";
};
doCheck = true;
passthru.tests = {
version = testVersion { package = hello; };
invariant-under-noXlibs =
testEqualDerivation
"hello must not be rebuilt when environment.noXlibs is set."
hello
(nixos { environment.noXlibs = true; }).pkgs.hello;
};
meta = with lib; {
description = "A program that produces a familiar, friendly greeting";
longDescription = ''
GNU Hello is a program that prints "Hello, world!" when you run it.
It is fully customizable.
'';
homepage = "https://www.gnu.org/software/hello/manual/";
changelog = "https://git.savannah.gnu.org/cgit/hello.git/plain/NEWS?h=v${version}";
license = licenses.gpl3Plus;
maintainers = [ maintainers.eelco ];
platforms = platforms.all;
};
}

View file

@ -0,0 +1,43 @@
{
lib,
stdenv,
fetchurl,
nixos,
testVersion,
testEqualDerivation,
hello,
}:
stdenv.mkDerivation rec {
pname = "hello";
version = "2.12";
src = fetchurl {
url = "mirror://gnu/hello/${pname}-${version}.tar.gz";
sha256 = "1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g";
};
doCheck = true;
passthru.tests = {
version = testVersion {package = hello;};
invariant-under-noXlibs =
testEqualDerivation
"hello must not be rebuilt when environment.noXlibs is set."
hello
(nixos {environment.noXlibs = true;}).pkgs.hello;
};
meta = with lib; {
description = "A program that produces a familiar, friendly greeting";
longDescription = ''
GNU Hello is a program that prints "Hello, world!" when you run it.
It is fully customizable.
'';
homepage = "https://www.gnu.org/software/hello/manual/";
changelog = "https://git.savannah.gnu.org/cgit/hello.git/plain/NEWS?h=v${version}";
license = licenses.gpl3Plus;
maintainers = [maintainers.eelco];
platforms = platforms.all;
};
}

View file

@ -0,0 +1,350 @@
{ config, lib, pkgs, ... }:
with lib;
let
inherit (config.boot) kernelPatches;
inherit (config.boot.kernel) features randstructSeed;
inherit (config.boot.kernelPackages) kernel;
kernelModulesConf = pkgs.writeText "nixos.conf"
''
${concatStringsSep "\n" config.boot.kernelModules}
'';
in
{
###### interface
options = {
boot.kernel.features = mkOption {
default = {};
example = literalExpression "{ debug = true; }";
internal = true;
description = ''
This option allows to enable or disable certain kernel features.
It's not API, because it's about kernel feature sets, that
make sense for specific use cases. Mostly along with programs,
which would have separate nixos options.
`grep features pkgs/os-specific/linux/kernel/common-config.nix`
'';
};
boot.kernelPackages = mkOption {
default = pkgs.linuxPackages;
type = types.unspecified // { merge = mergeEqualOption; };
apply = kernelPackages: kernelPackages.extend (self: super: {
kernel = super.kernel.override (originalArgs: {
inherit randstructSeed;
kernelPatches = (originalArgs.kernelPatches or []) ++ kernelPatches;
features = lib.recursiveUpdate super.kernel.features features;
});
});
# We don't want to evaluate all of linuxPackages for the manual
# - some of it might not even evaluate correctly.
defaultText = literalExpression "pkgs.linuxPackages";
example = literalExpression "pkgs.linuxKernel.packages.linux_5_10";
description = ''
This option allows you to override the Linux kernel used by
NixOS. Since things like external kernel module packages are
tied to the kernel you're using, it also overrides those.
This option is a function that takes Nixpkgs as an argument
(as a convenience), and returns an attribute set containing at
the very least an attribute <varname>kernel</varname>.
Additional attributes may be needed depending on your
configuration. For instance, if you use the NVIDIA X driver,
then it also needs to contain an attribute
<varname>nvidia_x11</varname>.
'';
};
boot.kernelPatches = mkOption {
type = types.listOf types.attrs;
default = [];
example = literalExpression "[ pkgs.kernelPatches.ubuntu_fan_4_4 ]";
description = "A list of additional patches to apply to the kernel.";
};
boot.kernel.randstructSeed = mkOption {
type = types.str;
default = "";
example = "my secret seed";
description = ''
Provides a custom seed for the <varname>RANDSTRUCT</varname> security
option of the Linux kernel. Note that <varname>RANDSTRUCT</varname> is
only enabled in NixOS hardened kernels. Using a custom seed requires
building the kernel and dependent packages locally, since this
customization happens at build time.
'';
};
boot.kernelParams = mkOption {
type = types.listOf (types.strMatching ''([^"[:space:]]|"[^"]*")+'' // {
name = "kernelParam";
description = "string, with spaces inside double quotes";
});
default = [ ];
description = "Parameters added to the kernel command line.";
};
boot.consoleLogLevel = mkOption {
type = types.int;
default = 4;
description = ''
The kernel console <literal>loglevel</literal>. All Kernel Messages with a log level smaller
than this setting will be printed to the console.
'';
};
boot.vesa = mkOption {
type = types.bool;
default = false;
description = ''
(Deprecated) This option, if set, activates the VESA 800x600 video
mode on boot and disables kernel modesetting. It is equivalent to
specifying <literal>[ "vga=0x317" "nomodeset" ]</literal> in the
<option>boot.kernelParams</option> option. This option is
deprecated as of 2020: Xorg now works better with modesetting, and
you might want a different VESA vga setting, anyway.
'';
};
boot.extraModulePackages = mkOption {
type = types.listOf types.package;
default = [];
example = literalExpression "[ config.boot.kernelPackages.nvidia_x11 ]";
description = "A list of additional packages supplying kernel modules.";
};
boot.kernelModules = mkOption {
type = types.listOf types.str;
default = [];
description = ''
The set of kernel modules to be loaded in the second stage of
the boot process. Note that modules that are needed to
mount the root file system should be added to
<option>boot.initrd.availableKernelModules</option> or
<option>boot.initrd.kernelModules</option>.
'';
};
boot.initrd.availableKernelModules = mkOption {
type = types.listOf types.str;
default = [];
example = [ "sata_nv" "ext3" ];
description = ''
The set of kernel modules in the initial ramdisk used during the
boot process. This set must include all modules necessary for
mounting the root device. That is, it should include modules
for the physical device (e.g., SCSI drivers) and for the file
system (e.g., ext3). The set specified here is automatically
closed under the module dependency relation, i.e., all
dependencies of the modules list here are included
automatically. The modules listed here are available in the
initrd, but are only loaded on demand (e.g., the ext3 module is
loaded automatically when an ext3 filesystem is mounted, and
modules for PCI devices are loaded when they match the PCI ID
of a device in your system). To force a module to be loaded,
include it in <option>boot.initrd.kernelModules</option>.
'';
};
boot.initrd.kernelModules = mkOption {
type = types.listOf types.str;
default = [];
description = "List of modules that are always loaded by the initrd.";
};
boot.initrd.includeDefaultModules = mkOption {
type = types.bool;
default = true;
description = ''
This option, if set, adds a collection of default kernel modules
to <option>boot.initrd.availableKernelModules</option> and
<option>boot.initrd.kernelModules</option>.
'';
};
system.modulesTree = mkOption {
type = types.listOf types.path;
internal = true;
default = [];
description = ''
Tree of kernel modules. This includes the kernel, plus modules
built outside of the kernel. Combine these into a single tree of
symlinks because modprobe only supports one directory.
'';
# Convert the list of path to only one path.
apply = pkgs.aggregateModules;
};
system.requiredKernelConfig = mkOption {
default = [];
example = literalExpression ''
with config.lib.kernelConfig; [
(isYes "MODULES")
(isEnabled "FB_CON_DECOR")
(isEnabled "BLK_DEV_INITRD")
]
'';
internal = true;
type = types.listOf types.attrs;
description = ''
This option allows modules to specify the kernel config options that
must be set (or unset) for the module to work. Please use the
lib.kernelConfig functions to build list elements.
'';
};
};
###### implementation
config = mkMerge
[ (mkIf config.boot.initrd.enable {
boot.initrd.availableKernelModules =
optionals config.boot.initrd.includeDefaultModules ([
# Note: most of these (especially the SATA/PATA modules)
# shouldn't be included by default since nixos-generate-config
# detects them, but I'm keeping them for now for backwards
# compatibility.
# Some SATA/PATA stuff.
"ahci"
"sata_nv"
"sata_via"
"sata_sis"
"sata_uli"
"ata_piix"
"pata_marvell"
# Standard SCSI stuff.
"sd_mod"
"sr_mod"
# SD cards and internal eMMC drives.
"mmc_block"
# Support USB keyboards, in case the boot fails and we only have
# a USB keyboard, or for LUKS passphrase prompt.
"uhci_hcd"
"ehci_hcd"
"ehci_pci"
"ohci_hcd"
"ohci_pci"
"xhci_hcd"
"xhci_pci"
"usbhid"
"hid_generic" "hid_lenovo" "hid_apple" "hid_roccat"
"hid_logitech_hidpp" "hid_logitech_dj" "hid_microsoft"
] ++ optionals pkgs.stdenv.hostPlatform.isx86 [
# Misc. x86 keyboard stuff.
"pcips2" "atkbd" "i8042"
# x86 RTC needed by the stage 2 init script.
"rtc_cmos"
]);
boot.initrd.kernelModules =
optionals config.boot.initrd.includeDefaultModules [
# For LVM.
"dm_mod"
];
})
(mkIf (!config.boot.isContainer) {
system.build = { inherit kernel; };
system.modulesTree = [ kernel ] ++ config.boot.extraModulePackages;
# Implement consoleLogLevel both in early boot and using sysctl
# (so you don't need to reboot to have changes take effect).
boot.kernelParams =
[ "loglevel=${toString config.boot.consoleLogLevel}" ] ++
optionals config.boot.vesa [ "vga=0x317" "nomodeset" ];
boot.kernel.sysctl."kernel.printk" = mkDefault config.boot.consoleLogLevel;
boot.kernelModules = [ "loop" "atkbd" ];
# The Linux kernel >= 2.6.27 provides firmware.
hardware.firmware = [ kernel ];
# Create /etc/modules-load.d/nixos.conf, which is read by
# systemd-modules-load.service to load required kernel modules.
environment.etc =
{ "modules-load.d/nixos.conf".source = kernelModulesConf;
};
systemd.services.systemd-modules-load =
{ wantedBy = [ "multi-user.target" ];
restartTriggers = [ kernelModulesConf ];
serviceConfig =
{ # Ignore failed module loads. Typically some of the
# modules in boot.kernelModules are "nice to have but
# not required" (e.g. acpi-cpufreq), so we don't want to
# barf on those.
SuccessExitStatus = "0 1";
};
};
lib.kernelConfig = {
isYes = option: {
assertion = config: config.isYes option;
message = "CONFIG_${option} is not yes!";
configLine = "CONFIG_${option}=y";
};
isNo = option: {
assertion = config: config.isNo option;
message = "CONFIG_${option} is not no!";
configLine = "CONFIG_${option}=n";
};
isModule = option: {
assertion = config: config.isModule option;
message = "CONFIG_${option} is not built as a module!";
configLine = "CONFIG_${option}=m";
};
### Usually you will just want to use these two
# True if yes or module
isEnabled = option: {
assertion = config: config.isEnabled option;
message = "CONFIG_${option} is not enabled!";
configLine = "CONFIG_${option}=y";
};
# True if no or omitted
isDisabled = option: {
assertion = config: config.isDisabled option;
message = "CONFIG_${option} is not disabled!";
configLine = "CONFIG_${option}=n";
};
};
# The config options that all modules can depend upon
system.requiredKernelConfig = with config.lib.kernelConfig;
[
# !!! Should this really be needed?
(isYes "MODULES")
(isYes "BINFMT_ELF")
] ++ (optional (randstructSeed != "") (isYes "GCC_PLUGIN_RANDSTRUCT"));
# nixpkgs kernels are assumed to have all required features
assertions = if config.boot.kernelPackages.kernel ? features then [] else
let cfg = config.boot.kernelPackages.kernel.config; in map (attrs:
{ assertion = attrs.assertion cfg; inherit (attrs) message; }
) config.system.requiredKernelConfig;
})
];
}

View file

@ -0,0 +1,361 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
inherit (config.boot) kernelPatches;
inherit (config.boot.kernel) features randstructSeed;
inherit (config.boot.kernelPackages) kernel;
kernelModulesConf =
pkgs.writeText "nixos.conf"
''
${concatStringsSep "\n" config.boot.kernelModules}
'';
in {
###### interface
options = {
boot.kernel.features = mkOption {
default = {};
example = literalExpression "{ debug = true; }";
internal = true;
description = ''
This option allows to enable or disable certain kernel features.
It's not API, because it's about kernel feature sets, that
make sense for specific use cases. Mostly along with programs,
which would have separate nixos options.
`grep features pkgs/os-specific/linux/kernel/common-config.nix`
'';
};
boot.kernelPackages = mkOption {
default = pkgs.linuxPackages;
type = types.unspecified // {merge = mergeEqualOption;};
apply = kernelPackages:
kernelPackages.extend (self: super: {
kernel = super.kernel.override (originalArgs: {
inherit randstructSeed;
kernelPatches = (originalArgs.kernelPatches or []) ++ kernelPatches;
features = lib.recursiveUpdate super.kernel.features features;
});
});
# We don't want to evaluate all of linuxPackages for the manual
# - some of it might not even evaluate correctly.
defaultText = literalExpression "pkgs.linuxPackages";
example = literalExpression "pkgs.linuxKernel.packages.linux_5_10";
description = ''
This option allows you to override the Linux kernel used by
NixOS. Since things like external kernel module packages are
tied to the kernel you're using, it also overrides those.
This option is a function that takes Nixpkgs as an argument
(as a convenience), and returns an attribute set containing at
the very least an attribute <varname>kernel</varname>.
Additional attributes may be needed depending on your
configuration. For instance, if you use the NVIDIA X driver,
then it also needs to contain an attribute
<varname>nvidia_x11</varname>.
'';
};
boot.kernelPatches = mkOption {
type = types.listOf types.attrs;
default = [];
example = literalExpression "[ pkgs.kernelPatches.ubuntu_fan_4_4 ]";
description = "A list of additional patches to apply to the kernel.";
};
boot.kernel.randstructSeed = mkOption {
type = types.str;
default = "";
example = "my secret seed";
description = ''
Provides a custom seed for the <varname>RANDSTRUCT</varname> security
option of the Linux kernel. Note that <varname>RANDSTRUCT</varname> is
only enabled in NixOS hardened kernels. Using a custom seed requires
building the kernel and dependent packages locally, since this
customization happens at build time.
'';
};
boot.kernelParams = mkOption {
type = types.listOf (types.strMatching ''([^"[:space:]]|"[^"]*")+''
// {
name = "kernelParam";
description = "string, with spaces inside double quotes";
});
default = [];
description = "Parameters added to the kernel command line.";
};
boot.consoleLogLevel = mkOption {
type = types.int;
default = 4;
description = ''
The kernel console <literal>loglevel</literal>. All Kernel Messages with a log level smaller
than this setting will be printed to the console.
'';
};
boot.vesa = mkOption {
type = types.bool;
default = false;
description = ''
(Deprecated) This option, if set, activates the VESA 800x600 video
mode on boot and disables kernel modesetting. It is equivalent to
specifying <literal>[ "vga=0x317" "nomodeset" ]</literal> in the
<option>boot.kernelParams</option> option. This option is
deprecated as of 2020: Xorg now works better with modesetting, and
you might want a different VESA vga setting, anyway.
'';
};
boot.extraModulePackages = mkOption {
type = types.listOf types.package;
default = [];
example = literalExpression "[ config.boot.kernelPackages.nvidia_x11 ]";
description = "A list of additional packages supplying kernel modules.";
};
boot.kernelModules = mkOption {
type = types.listOf types.str;
default = [];
description = ''
The set of kernel modules to be loaded in the second stage of
the boot process. Note that modules that are needed to
mount the root file system should be added to
<option>boot.initrd.availableKernelModules</option> or
<option>boot.initrd.kernelModules</option>.
'';
};
boot.initrd.availableKernelModules = mkOption {
type = types.listOf types.str;
default = [];
example = ["sata_nv" "ext3"];
description = ''
The set of kernel modules in the initial ramdisk used during the
boot process. This set must include all modules necessary for
mounting the root device. That is, it should include modules
for the physical device (e.g., SCSI drivers) and for the file
system (e.g., ext3). The set specified here is automatically
closed under the module dependency relation, i.e., all
dependencies of the modules list here are included
automatically. The modules listed here are available in the
initrd, but are only loaded on demand (e.g., the ext3 module is
loaded automatically when an ext3 filesystem is mounted, and
modules for PCI devices are loaded when they match the PCI ID
of a device in your system). To force a module to be loaded,
include it in <option>boot.initrd.kernelModules</option>.
'';
};
boot.initrd.kernelModules = mkOption {
type = types.listOf types.str;
default = [];
description = "List of modules that are always loaded by the initrd.";
};
boot.initrd.includeDefaultModules = mkOption {
type = types.bool;
default = true;
description = ''
This option, if set, adds a collection of default kernel modules
to <option>boot.initrd.availableKernelModules</option> and
<option>boot.initrd.kernelModules</option>.
'';
};
system.modulesTree = mkOption {
type = types.listOf types.path;
internal = true;
default = [];
description = ''
Tree of kernel modules. This includes the kernel, plus modules
built outside of the kernel. Combine these into a single tree of
symlinks because modprobe only supports one directory.
'';
# Convert the list of path to only one path.
apply = pkgs.aggregateModules;
};
system.requiredKernelConfig = mkOption {
default = [];
example = literalExpression ''
with config.lib.kernelConfig; [
(isYes "MODULES")
(isEnabled "FB_CON_DECOR")
(isEnabled "BLK_DEV_INITRD")
]
'';
internal = true;
type = types.listOf types.attrs;
description = ''
This option allows modules to specify the kernel config options that
must be set (or unset) for the module to work. Please use the
lib.kernelConfig functions to build list elements.
'';
};
};
###### implementation
config =
mkMerge
[
(mkIf config.boot.initrd.enable {
boot.initrd.availableKernelModules = optionals config.boot.initrd.includeDefaultModules ([
# Note: most of these (especially the SATA/PATA modules)
# shouldn't be included by default since nixos-generate-config
# detects them, but I'm keeping them for now for backwards
# compatibility.
# Some SATA/PATA stuff.
"ahci"
"sata_nv"
"sata_via"
"sata_sis"
"sata_uli"
"ata_piix"
"pata_marvell"
# Standard SCSI stuff.
"sd_mod"
"sr_mod"
# SD cards and internal eMMC drives.
"mmc_block"
# Support USB keyboards, in case the boot fails and we only have
# a USB keyboard, or for LUKS passphrase prompt.
"uhci_hcd"
"ehci_hcd"
"ehci_pci"
"ohci_hcd"
"ohci_pci"
"xhci_hcd"
"xhci_pci"
"usbhid"
"hid_generic"
"hid_lenovo"
"hid_apple"
"hid_roccat"
"hid_logitech_hidpp"
"hid_logitech_dj"
"hid_microsoft"
]
++ optionals pkgs.stdenv.hostPlatform.isx86 [
# Misc. x86 keyboard stuff.
"pcips2"
"atkbd"
"i8042"
# x86 RTC needed by the stage 2 init script.
"rtc_cmos"
]);
boot.initrd.kernelModules = optionals config.boot.initrd.includeDefaultModules [
# For LVM.
"dm_mod"
];
})
(mkIf (!config.boot.isContainer) {
system.build = {inherit kernel;};
system.modulesTree = [kernel] ++ config.boot.extraModulePackages;
# Implement consoleLogLevel both in early boot and using sysctl
# (so you don't need to reboot to have changes take effect).
boot.kernelParams =
["loglevel=${toString config.boot.consoleLogLevel}"]
++ optionals config.boot.vesa ["vga=0x317" "nomodeset"];
boot.kernel.sysctl."kernel.printk" = mkDefault config.boot.consoleLogLevel;
boot.kernelModules = ["loop" "atkbd"];
# The Linux kernel >= 2.6.27 provides firmware.
hardware.firmware = [kernel];
# Create /etc/modules-load.d/nixos.conf, which is read by
# systemd-modules-load.service to load required kernel modules.
environment.etc = {
"modules-load.d/nixos.conf".source = kernelModulesConf;
};
systemd.services.systemd-modules-load = {
wantedBy = ["multi-user.target"];
restartTriggers = [kernelModulesConf];
serviceConfig = {
# Ignore failed module loads. Typically some of the
# modules in boot.kernelModules are "nice to have but
# not required" (e.g. acpi-cpufreq), so we don't want to
# barf on those.
SuccessExitStatus = "0 1";
};
};
lib.kernelConfig = {
isYes = option: {
assertion = config: config.isYes option;
message = "CONFIG_${option} is not yes!";
configLine = "CONFIG_${option}=y";
};
isNo = option: {
assertion = config: config.isNo option;
message = "CONFIG_${option} is not no!";
configLine = "CONFIG_${option}=n";
};
isModule = option: {
assertion = config: config.isModule option;
message = "CONFIG_${option} is not built as a module!";
configLine = "CONFIG_${option}=m";
};
### Usually you will just want to use these two
# True if yes or module
isEnabled = option: {
assertion = config: config.isEnabled option;
message = "CONFIG_${option} is not enabled!";
configLine = "CONFIG_${option}=y";
};
# True if no or omitted
isDisabled = option: {
assertion = config: config.isDisabled option;
message = "CONFIG_${option} is not disabled!";
configLine = "CONFIG_${option}=n";
};
};
# The config options that all modules can depend upon
system.requiredKernelConfig = with config.lib.kernelConfig;
[
# !!! Should this really be needed?
(isYes "MODULES")
(isYes "BINFMT_ELF")
]
++ (optional (randstructSeed != "") (isYes "GCC_PLUGIN_RANDSTRUCT"));
# nixpkgs kernels are assumed to have all required features
assertions =
if config.boot.kernelPackages.kernel ? features
then []
else let
cfg = config.boot.kernelPackages.kernel.config;
in
map (
attrs: {
assertion = attrs.assertion cfg;
inherit (attrs) message;
}
)
config.system.requiredKernelConfig;
})
];
}

View file

@ -0,0 +1,269 @@
{
# foo
stdenv
# foo
,
# foo
lib
# foo
,
# foo
fetchFromGitLab
# foo
,
# foo
cairo
# foo
,
# foo
desktop-file-utils
# foo
,
# foo
gettext
# foo
,
# foo
glib
# foo
,
# foo
gtk4
# foo
,
# foo
libadwaita
# foo
,
# foo
meson
# foo
,
# foo
ninja
# foo
,
# foo
pango
# foo
,
# foo
pkg-config
# foo
,
# foo
python3
# foo
,
# foo
rustPlatform
# foo
,
# foo
wrapGAppsHook4
# foo
}:
# foo
stdenv.mkDerivation
# foo
rec
# foo
{
# foo
pname
# foo
=
# foo
"contrast";
# foo
version
# foo
=
# foo
"0.0.5";
# foo
src
# foo
=
# foo
fetchFromGitLab
# foo
{
# foo
domain
# foo
=
# foo
"gitlab.gnome.org";
# foo
group
# foo
=
# foo
"World";
# foo
owner
# foo
=
# foo
"design";
# foo
repo
# foo
=
# foo
"contrast";
# foo
rev
# foo
=
# foo
version;
# foo
sha256
# foo
=
# foo
"cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0=";
# foo
};
# foo
cargoDeps
# foo
=
# foo
rustPlatform.fetchCargoTarball
# foo
{
# foo
inherit
# foo
src;
# foo
name
# foo
=
# foo
"${pname}-${version}";
# foo
hash
# foo
=
# foo
"sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ=";
# foo
};
# foo
nativeBuildInputs
# foo
=
# foo
[
# foo
desktop-file-utils
# foo
gettext
# foo
meson
# foo
ninja
# foo
pkg-config
# foo
python3
# foo
rustPlatform.rust.cargo
# foo
rustPlatform.cargoSetupHook
# foo
rustPlatform.rust.rustc
# foo
wrapGAppsHook4
# foo
glib
# foo
# for glib-compile-resources
# foo
];
# foo
buildInputs
# foo
=
# foo
[
# foo
cairo
# foo
glib
# foo
gtk4
# foo
libadwaita
# foo
pango
# foo
];
# foo
postPatch
# foo
=
# foo
''
patchShebangs build-aux/meson_post_install.py
# https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23
substituteInPlace build-aux/meson_post_install.py \
--replace "gtk-update-icon-cache" "gtk4-update-icon-cache"
'';
# foo
meta
# foo
=
# foo
with
# foo
lib;
# foo
{
# foo
description
# foo
=
# foo
"Checks whether the contrast between two colors meet the WCAG requirements";
# foo
homepage
# foo
=
# foo
"https://gitlab.gnome.org/World/design/contrast";
# foo
license
# foo
=
# foo
licenses.gpl3Plus;
# foo
maintainers
# foo
=
# foo
with
# foo
maintainers;
# foo
[
# foo
jtojnar
# foo
];
# foo
platforms
# foo
=
# foo
platforms.unix;
# foo
};
# foo
}

View file

@ -0,0 +1,255 @@
{
# foo
stdenv,
# foo
# foo
lib,
# foo
# foo
fetchFromGitLab,
# foo
# foo
cairo,
# foo
# foo
desktop-file-utils,
# foo
# foo
gettext,
# foo
# foo
glib,
# foo
# foo
gtk4,
# foo
# foo
libadwaita,
# foo
# foo
meson,
# foo
# foo
ninja,
# foo
# foo
pango,
# foo
# foo
pkg-config,
# foo
# foo
python3,
# foo
# foo
rustPlatform,
# foo
# foo
wrapGAppsHook4,
# foo
}:
# foo
stdenv.mkDerivation
# foo
rec
# foo
{
# foo
pname
# foo
=
# foo
"contrast";
# foo
version
# foo
=
# foo
"0.0.5";
# foo
src
# foo
=
# foo
fetchFromGitLab
# foo
{
# foo
domain
# foo
=
# foo
"gitlab.gnome.org";
# foo
group
# foo
=
# foo
"World";
# foo
owner
# foo
=
# foo
"design";
# foo
repo
# foo
=
# foo
"contrast";
# foo
rev
# foo
=
# foo
version;
# foo
sha256
# foo
=
# foo
"cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0=";
# foo
};
# foo
cargoDeps
# foo
=
# foo
rustPlatform.fetchCargoTarball
# foo
{
# foo
inherit
# foo
src
;
# foo
name
# foo
=
# foo
"${pname}-${version}";
# foo
hash
# foo
=
# foo
"sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ=";
# foo
};
# foo
nativeBuildInputs
# foo
=
# foo
[
# foo
desktop-file-utils
# foo
gettext
# foo
meson
# foo
ninja
# foo
pkg-config
# foo
python3
# foo
rustPlatform.rust.cargo
# foo
rustPlatform.cargoSetupHook
# foo
rustPlatform.rust.rustc
# foo
wrapGAppsHook4
# foo
glib
# foo
# for glib-compile-resources
# foo
];
# foo
buildInputs
# foo
=
# foo
[
# foo
cairo
# foo
glib
# foo
gtk4
# foo
libadwaita
# foo
pango
# foo
];
# foo
postPatch
# foo
=
# foo
''
patchShebangs build-aux/meson_post_install.py
# https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23
substituteInPlace build-aux/meson_post_install.py \
--replace "gtk-update-icon-cache" "gtk4-update-icon-cache"
'';
# foo
meta
# foo
=
# foo
with
# foo
lib;
# foo
{
# foo
description
# foo
=
# foo
"Checks whether the contrast between two colors meet the WCAG requirements";
# foo
homepage
# foo
=
# foo
"https://gitlab.gnome.org/World/design/contrast";
# foo
license
# foo
=
# foo
licenses.gpl3Plus;
# foo
maintainers
# foo
=
# foo
with
# foo
maintainers;
# foo
[
# foo
jtojnar
# foo
];
# foo
platforms
# foo
=
# foo
platforms.unix;
# foo
};
# foo
}

View file

@ -0,0 +1,31 @@
{
lib = {
/* Concatenate two lists
Type: concat :: [a] -> [a] -> [a]
Example:
concat [ 1 2 ] [ 3 4 ]
=> [ 1 2 3 4 ]
*/
concat = x: y: x ++ y;
};
options = {
boot.kernel.features = mkOption {
default = {};
example = literalExpression "{ debug = true; }";
internal = true;
description = ''
This option allows to enable or disable certain kernel features.
It's not API, because it's about kernel feature sets, that
make sense for specific use cases. Mostly along with programs,
which would have separate nixos options.
`grep features pkgs/os-specific/linux/kernel/common-config.nix`
'';
};
};
}

View file

@ -0,0 +1,29 @@
{
lib = {
/*
Concatenate two lists
Type: concat :: [a] -> [a] -> [a]
Example:
concat [ 1 2 ] [ 3 4 ]
=> [ 1 2 3 4 ]
*/
concat = x: y: x ++ y;
};
options = {
boot.kernel.features = mkOption {
default = {};
example = literalExpression "{ debug = true; }";
internal = true;
description = ''
This option allows to enable or disable certain kernel features.
It's not API, because it's about kernel feature sets, that
make sense for specific use cases. Mostly along with programs,
which would have separate nixos options.
`grep features pkgs/os-specific/linux/kernel/common-config.nix`
'';
};
};
}

View file

@ -0,0 +1,7 @@
{ stdenv , lib , fetchFromGitLab , cairo , desktop-file-utils , gettext , glib , gtk4 , libadwaita , meson , ninja , pango , pkg-config , python3 , rustPlatform , wrapGAppsHook4 }: stdenv.mkDerivation rec { pname = "contrast"; version = "0.0.5"; src = fetchFromGitLab { domain = "gitlab.gnome.org"; group = "World"; owner = "design"; repo = "contrast"; rev = version; sha256 = "cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0="; }; cargoDeps = rustPlatform.fetchCargoTarball { inherit src; name = "${pname}-${version}"; hash = "sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ="; }; nativeBuildInputs = [ desktop-file-utils gettext meson ninja pkg-config python3 rustPlatform.rust.cargo rustPlatform.cargoSetupHook rustPlatform.rust.rustc wrapGAppsHook4 glib # for glib-compile-resources
]; buildInputs = [ cairo glib gtk4 libadwaita pango ]; postPatch = ''
patchShebangs build-aux/meson_post_install.py
# https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23
substituteInPlace build-aux/meson_post_install.py \
--replace "gtk-update-icon-cache" "gtk4-update-icon-cache"
''; meta = with lib; { description = "Checks whether the contrast between two colors meet the WCAG requirements"; homepage = "https://gitlab.gnome.org/World/design/contrast"; license = licenses.gpl3Plus; maintainers = with maintainers; [ jtojnar ]; platforms = platforms.unix; }; }

View file

@ -0,0 +1,62 @@
{
stdenv,
lib,
fetchFromGitLab,
cairo,
desktop-file-utils,
gettext,
glib,
gtk4,
libadwaita,
meson,
ninja,
pango,
pkg-config,
python3,
rustPlatform,
wrapGAppsHook4,
}:
stdenv.mkDerivation rec {
pname = "contrast";
version = "0.0.5";
src = fetchFromGitLab {
domain = "gitlab.gnome.org";
group = "World";
owner = "design";
repo = "contrast";
rev = version;
sha256 = "cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0=";
};
cargoDeps = rustPlatform.fetchCargoTarball {
inherit src;
name = "${pname}-${version}";
hash = "sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ=";
};
nativeBuildInputs = [
desktop-file-utils
gettext
meson
ninja
pkg-config
python3
rustPlatform.rust.cargo
rustPlatform.cargoSetupHook
rustPlatform.rust.rustc
wrapGAppsHook4
glib # for glib-compile-resources
];
buildInputs = [cairo glib gtk4 libadwaita pango];
postPatch = ''
patchShebangs build-aux/meson_post_install.py
# https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23
substituteInPlace build-aux/meson_post_install.py \
--replace "gtk-update-icon-cache" "gtk4-update-icon-cache"
'';
meta = with lib; {
description = "Checks whether the contrast between two colors meet the WCAG requirements";
homepage = "https://gitlab.gnome.org/World/design/contrast";
license = licenses.gpl3Plus;
maintainers = with maintainers; [jtojnar];
platforms = platforms.unix;
};
}

View file

@ -0,0 +1,7 @@
{/*Foo*/stdenv/*Foo*/,/*Foo*/lib/*Foo*/,/*Foo*/fetchFromGitLab/*Foo*/,/*Foo*/cairo/*Foo*/,/*Foo*/desktop-file-utils/*Foo*/,/*Foo*/gettext/*Foo*/,/*Foo*/glib/*Foo*/,/*Foo*/gtk4/*Foo*/,/*Foo*/libadwaita/*Foo*/,/*Foo*/meson/*Foo*/,/*Foo*/ninja/*Foo*/,/*Foo*/pango/*Foo*/,/*Foo*/pkg-config/*Foo*/,/*Foo*/python3/*Foo*/,/*Foo*/rustPlatform/*Foo*/,/*Foo*/wrapGAppsHook4/*Foo*/}:/*Foo*/stdenv.mkDerivation/*Foo*/rec/*Foo*/{/*Foo*/pname/*Foo*/=/*Foo*/"contrast";/*Foo*/version/*Foo*/=/*Foo*/"0.0.5";/*Foo*/src/*Foo*/=/*Foo*/fetchFromGitLab/*Foo*/{/*Foo*/domain/*Foo*/=/*Foo*/"gitlab.gnome.org";/*Foo*/group/*Foo*/=/*Foo*/"World";/*Foo*/owner/*Foo*/=/*Foo*/"design";/*Foo*/repo/*Foo*/=/*Foo*/"contrast";/*Foo*/rev/*Foo*/=/*Foo*/version;/*Foo*/sha256/*Foo*/=/*Foo*/"cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0=";/*Foo*/};/*Foo*/cargoDeps/*Foo*/=/*Foo*/rustPlatform.fetchCargoTarball/*Foo*/{/*Foo*/inherit/*Foo*/src;/*Foo*/name/*Foo*/=/*Foo*/"${pname}-${version}";/*Foo*/hash/*Foo*/=/*Foo*/"sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ=";/*Foo*/};/*Foo*/nativeBuildInputs/*Foo*/=/*Foo*/[/*Foo*/desktop-file-utils/*Foo*/gettext/*Foo*/meson/*Foo*/ninja/*Foo*/pkg-config/*Foo*/python3/*Foo*/rustPlatform.rust.cargo/*Foo*/rustPlatform.cargoSetupHook/*Foo*/rustPlatform.rust.rustc/*Foo*/wrapGAppsHook4/*Foo*/glib/*Foo*/# for glib-compile-resources
/*Foo*/];/*Foo*/buildInputs/*Foo*/=/*Foo*/[/*Foo*/cairo/*Foo*/glib/*Foo*/gtk4/*Foo*/libadwaita/*Foo*/pango/*Foo*/];/*Foo*/postPatch/*Foo*/=/*Foo*/''
patchShebangs build-aux/meson_post_install.py
# https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23
substituteInPlace build-aux/meson_post_install.py \
--replace "gtk-update-icon-cache" "gtk4-update-icon-cache"
'';/*Foo*/meta/*Foo*/=/*Foo*/with/*Foo*/lib;/*Foo*/{/*Foo*/description/*Foo*/=/*Foo*/"Checks whether the contrast between two colors meet the WCAG requirements";/*Foo*/homepage/*Foo*/=/*Foo*/"https://gitlab.gnome.org/World/design/contrast";/*Foo*/license/*Foo*/=/*Foo*/licenses.gpl3Plus;/*Foo*/maintainers/*Foo*/=/*Foo*/with/*Foo*/maintainers;/*Foo*/[/*Foo*/jtojnar/*Foo*/];/*Foo*/platforms/*Foo*/=/*Foo*/platforms.unix;/*Foo*/};/*Foo*/}

View file

@ -0,0 +1,516 @@
{
/*
Foo
*/
stdenv,
/*
Foo
*/
/*
Foo
*/
lib,
/*
Foo
*/
/*
Foo
*/
fetchFromGitLab,
/*
Foo
*/
/*
Foo
*/
cairo,
/*
Foo
*/
/*
Foo
*/
desktop-file-utils,
/*
Foo
*/
/*
Foo
*/
gettext,
/*
Foo
*/
/*
Foo
*/
glib,
/*
Foo
*/
/*
Foo
*/
gtk4,
/*
Foo
*/
/*
Foo
*/
libadwaita,
/*
Foo
*/
/*
Foo
*/
meson,
/*
Foo
*/
/*
Foo
*/
ninja,
/*
Foo
*/
/*
Foo
*/
pango,
/*
Foo
*/
/*
Foo
*/
pkg-config,
/*
Foo
*/
/*
Foo
*/
python3,
/*
Foo
*/
/*
Foo
*/
rustPlatform,
/*
Foo
*/
/*
Foo
*/
wrapGAppsHook4,
/*
Foo
*/
}:
/*
Foo
*/
stdenv.mkDerivation
/*
Foo
*/
rec
/*
Foo
*/
{
/*
Foo
*/
pname
/*
Foo
*/
=
/*
Foo
*/
"contrast";
/*
Foo
*/
version
/*
Foo
*/
=
/*
Foo
*/
"0.0.5";
/*
Foo
*/
src
/*
Foo
*/
=
/*
Foo
*/
fetchFromGitLab
/*
Foo
*/
{
/*
Foo
*/
domain
/*
Foo
*/
=
/*
Foo
*/
"gitlab.gnome.org";
/*
Foo
*/
group
/*
Foo
*/
=
/*
Foo
*/
"World";
/*
Foo
*/
owner
/*
Foo
*/
=
/*
Foo
*/
"design";
/*
Foo
*/
repo
/*
Foo
*/
=
/*
Foo
*/
"contrast";
/*
Foo
*/
rev
/*
Foo
*/
=
/*
Foo
*/
version;
/*
Foo
*/
sha256
/*
Foo
*/
=
/*
Foo
*/
"cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0=";
/*
Foo
*/
};
/*
Foo
*/
cargoDeps
/*
Foo
*/
=
/*
Foo
*/
rustPlatform.fetchCargoTarball
/*
Foo
*/
{
/*
Foo
*/
inherit
/*
Foo
*/
src
;
/*
Foo
*/
name
/*
Foo
*/
=
/*
Foo
*/
"${pname}-${version}";
/*
Foo
*/
hash
/*
Foo
*/
=
/*
Foo
*/
"sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ=";
/*
Foo
*/
};
/*
Foo
*/
nativeBuildInputs
/*
Foo
*/
=
/*
Foo
*/
[
/*
Foo
*/
desktop-file-utils
/*
Foo
*/
gettext
/*
Foo
*/
meson
/*
Foo
*/
ninja
/*
Foo
*/
pkg-config
/*
Foo
*/
python3
/*
Foo
*/
rustPlatform.rust.cargo
/*
Foo
*/
rustPlatform.cargoSetupHook
/*
Foo
*/
rustPlatform.rust.rustc
/*
Foo
*/
wrapGAppsHook4
/*
Foo
*/
glib
/*
Foo
*/
# for glib-compile-resources
/*
Foo
*/
];
/*
Foo
*/
buildInputs
/*
Foo
*/
=
/*
Foo
*/
[
/*
Foo
*/
cairo
/*
Foo
*/
glib
/*
Foo
*/
gtk4
/*
Foo
*/
libadwaita
/*
Foo
*/
pango
/*
Foo
*/
];
/*
Foo
*/
postPatch
/*
Foo
*/
=
/*
Foo
*/
''
patchShebangs build-aux/meson_post_install.py
# https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23
substituteInPlace build-aux/meson_post_install.py \
--replace "gtk-update-icon-cache" "gtk4-update-icon-cache"
'';
/*
Foo
*/
meta
/*
Foo
*/
=
/*
Foo
*/
with
/*
Foo
*/
lib;
/*
Foo
*/
{
/*
Foo
*/
description
/*
Foo
*/
=
/*
Foo
*/
"Checks whether the contrast between two colors meet the WCAG requirements";
/*
Foo
*/
homepage
/*
Foo
*/
=
/*
Foo
*/
"https://gitlab.gnome.org/World/design/contrast";
/*
Foo
*/
license
/*
Foo
*/
=
/*
Foo
*/
licenses.gpl3Plus;
/*
Foo
*/
maintainers
/*
Foo
*/
=
/*
Foo
*/
with
/*
Foo
*/
maintainers;
/*
Foo
*/
[
/*
Foo
*/
jtojnar
/*
Foo
*/
];
/*
Foo
*/
platforms
/*
Foo
*/
=
/*
Foo
*/
platforms.unix;
/*
Foo
*/
};
/*
Foo
*/
}

View file

@ -0,0 +1,327 @@
{
config,
lib,
pkgs,
...
}:
with
lib;
let
inherit
(config.boot)
kernelPatches;
inherit
(config.boot.kernel)
features
randstructSeed;
inherit
(config.boot.kernelPackages)
kernel;
kernelModulesConf
=
pkgs.writeText
"nixos.conf"
''
${concatStringsSep "\n" config.boot.kernelModules}
'';
in
{
###### interface
options
=
{
boot.kernel.features
=
mkOption
{
default
=
{};
example
=
literalExpression
"{debug= true;}";
internal
=
true;
description
=
''
This option allows to enable or disable certain kernel features.
It's not API, because it's about kernel feature sets, that
make sense for specific use cases. Mostly along with programs,
which would have separate nixos options.
`grep features pkgs/os-specific/linux/kernel/common-config.nix`
'';
};
boot.kernelPackages
=
mkOption
{
default
=
pkgs.linuxPackages;
type
=
types.unspecified
//
{
merge
=
mergeEqualOption;
};
apply
=
kernelPackages:
kernelPackages.extend
(self:
super:
{
kernel
=
super.kernel.override
(originalArgs:
{
inherit
randstructSeed;
kernelPatches
=
(originalArgs.kernelPatches
or
[])
++
kernelPatches;
features
=
lib.recursiveUpdate
super.kernel.features
features;
});
});
# We don't want to evaluate all of linuxPackages for the manual
# - some of it might not even evaluate correctly.
defaultText
=
literalExpression
"pkgs.linuxPackages";
example
=
literalExpression
"pkgs.linuxKernel.packages.linux_5_10";
description
=
''
This option allows you to override the Linux kernel used by
NixOS. Since things like external kernel module packages are
tied to the kernel you're using, it also overrides those.
This option is a function that takes Nixpkgs as an argument
(as a convenience), and returns an attribute set containing at
the very least an attribute <varname>kernel</varname>.
Additional attributes may be needed depending on your
configuration. For instance, if you use the NVIDIA X driver,
then it also needs to contain an attribute
<varname>nvidia_x11</varname>.
'';
};
boot.kernelPatches
=
mkOption
{
type
=
types.listOf
types.attrs;
default
=
[];
example
=
literalExpression
"[ pkgs.kernelPatches.ubuntu_fan_4_4 ]";
description = "A list of additional patches to apply to the kernel.";
};
};}

View file

@ -0,0 +1,130 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
inherit
(config.boot)
kernelPatches
;
inherit
(config.boot.kernel)
features
randstructSeed
;
inherit
(config.boot.kernelPackages)
kernel
;
kernelModulesConf =
pkgs.writeText
"nixos.conf"
''
${concatStringsSep "\n" config.boot.kernelModules}
'';
in {
###### interface
options = {
boot.kernel.features =
mkOption
{
default = {};
example =
literalExpression
"{debug= true;}";
internal =
true;
description = ''
This option allows to enable or disable certain kernel features.
It's not API, because it's about kernel feature sets, that
make sense for specific use cases. Mostly along with programs,
which would have separate nixos options.
`grep features pkgs/os-specific/linux/kernel/common-config.nix`
'';
};
boot.kernelPackages =
mkOption
{
default =
pkgs.linuxPackages;
type =
types.unspecified
// {
merge =
mergeEqualOption;
};
apply = kernelPackages:
kernelPackages.extend
(self: super: {
kernel =
super.kernel.override
(originalArgs: {
inherit
randstructSeed
;
kernelPatches =
(originalArgs.kernelPatches
or [])
++ kernelPatches;
features =
lib.recursiveUpdate
super.kernel.features
features;
});
});
# We don't want to evaluate all of linuxPackages for the manual
# - some of it might not even evaluate correctly.
defaultText =
literalExpression
"pkgs.linuxPackages";
example =
literalExpression
"pkgs.linuxKernel.packages.linux_5_10";
description = ''
This option allows you to override the Linux kernel used by
NixOS. Since things like external kernel module packages are
tied to the kernel you're using, it also overrides those.
This option is a function that takes Nixpkgs as an argument
(as a convenience), and returns an attribute set containing at
the very least an attribute <varname>kernel</varname>.
Additional attributes may be needed depending on your
configuration. For instance, if you use the NVIDIA X driver,
then it also needs to contain an attribute
<varname>nvidia_x11</varname>.
'';
};
boot.kernelPatches =
mkOption
{
type =
types.listOf
types.attrs;
default = [];
example =
literalExpression
"[ pkgs.kernelPatches.ubuntu_fan_4_4 ]";
description = "A list of additional patches to apply to the kernel.";
};
};
}