1
0
Fork 0
mirror of https://github.com/LnL7/nix-darwin.git synced 2024-12-15 17:51:01 +00:00

Merge pull request #723 from emilazy/rationalize-nixpkgs-handling

Rationalize handling of Nixpkgs
This commit is contained in:
Daiderd Jordan 2023-07-09 12:34:19 +02:00 committed by GitHub
commit 66a3047fa8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 391 additions and 199 deletions

View file

@ -85,39 +85,29 @@ A minimal example of using an existing configuration.nix:
darwin.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, darwin, nixpkgs }: {
outputs = inputs@{ self, darwin, nixpkgs }: {
darwinConfigurations."Johns-MacBook" = darwin.lib.darwinSystem {
system = "x86_64-darwin";
modules = [ ./configuration.nix ];
};
};
}
```
Inputs from the flake can also be passed to `darwinSystem`. These inputs are then
Inputs from the flake can also be passed into `darwinSystem`. These inputs are then
accessible as an argument `inputs`, similar to `pkgs` and `lib`, inside the configuration.
```nix
# in flake.nix
darwin.lib.darwinSystem {
system = "x86_64-darwin";
modules = [ ./configuration.nix ];
inputs = { inherit darwin dotfiles nixpkgs; };
specialArgs = { inherit inputs; };
}
# in configuration.nix:
{ pkgs, lib, inputs }:
# inputs.darwin, inputs.dotfiles, and inputs.nixpkgs can be accessed here
```
Alternatively, `specialArgs` could be used:
```nix
darwin.lib.darwinSystem {
system = "x86_64-darwin";
modules = [ ./configuration.nix ];
specialArgs = { inherit darwin dotfiles nixpkgs; };
}
# in configuration.nix:
{ pkgs, lib, darwin, dotfiles, nixpkgs }:
# in configuration.nix
{ pkgs, lib, inputs }:
# inputs.self, inputs.darwin, and inputs.nixpkgs can be accessed here
```
Since the installer doesn't work with flakes out of the box yet, nix-darwin will need to

View file

@ -6,19 +6,16 @@
}:
let
evalConfig = import ./eval-config.nix { inherit lib; };
eval = evalConfig {
inherit system;
modules = [ configuration nixpkgsRevisionModule ];
inputs = { inherit nixpkgs; };
eval = import ./eval-config.nix {
inherit lib;
modules = [
configuration
{ nixpkgs.source = lib.mkDefault nixpkgs; }
] ++ lib.optional (system != null) {
nixpkgs.system = lib.mkDefault system;
};
};
nixpkgsRevisionModule =
if nixpkgs?rev && lib.isString nixpkgs.rev
then { system.nixpkgsRevision = nixpkgs.rev; }
else { };
# The source code of this repo needed by the [un]installers.
nix-darwin = lib.cleanSource (
lib.cleanSourceWith {

View file

@ -13,28 +13,30 @@ with pkgs;
let
lib = pkgs.lib;
gitHubDeclaration = user: repo: ref: subpath:
# Default to `master` if we don't know what revision the system
# configuration is using (custom nixpkgs, etc.).
let urlRef = if ref != null then ref else "master";
in {
url = "https://github.com/${user}/${repo}/blob/${urlRef}/${subpath}";
name = "<${repo}/${subpath}>";
};
optionsDoc = buildPackages.nixosOptionsDoc {
inherit options revision;
inherit options;
transformOptions = opt: opt // {
# Clean up declaration sites to not refer to the nix-darwin source tree.
# TODO: handle `extraSources`? (it's not set anywhere)
declarations = map
(decl:
if lib.hasPrefix (toString prefix) (toString decl) then
let
subpath = lib.removePrefix "/"
(lib.removePrefix (toString prefix) (toString decl));
in {
url = "https://github.com/LnL7/nix-darwin/blob/${revision}/${subpath}";
name = "<nix-darwin/${subpath}>";
}
gitHubDeclaration "LnL7" "nix-darwin" revision
(lib.removePrefix "/"
(lib.removePrefix (toString prefix) (toString decl)))
# TODO: handle this in a better way (may require upstream
# changes to nixpkgs)
else if decl == "lib/modules.nix" then
{
url = "https://github.com/NixOS/nixpkgs/blob/${nixpkgsRevision}/${decl}";
name = "<nixpkgs/${decl}>";
}
gitHubDeclaration "NixOS" "nixpkgs" nixpkgsRevision decl
else decl)
opt.declarations;
};
@ -73,7 +75,7 @@ in rec {
cp -r ${pkgs.documentation-highlighter} $dst/highlightjs
substitute ${./manual.md} manual.md \
--replace '@DARWIN_VERSION@' "${version}"\
--replace '@DARWIN_VERSION@' "${version}" \
--replace \
'@DARWIN_OPTIONS_JSON@' \
${optionsJSON}/share/doc/darwin/options.json
@ -82,7 +84,7 @@ in rec {
nixos-render-docs -j $NIX_BUILD_CORES manual html \
--manpage-urls ${pkgs.writeText "manpage-urls.json" "{}"} \
--revision ${lib.escapeShellArg revision} \
--generator "nixos-render-docs ${pkgs.lib.version}" \
--generator "nixos-render-docs ${lib.version}" \
--stylesheet style.css \
--stylesheet overrides.css \
--stylesheet highlightjs/mono-blue.css \

View file

@ -1,13 +1,5 @@
{ lib }:
let
nixpkgs-lib = lib;
in
{ system ? builtins.currentSystem or "x86_64-darwin"
, pkgs ? null
, lib ? nixpkgs-lib
{ lib
, modules
, inputs
, baseModules ? import ./modules/module-list.nix
, specialArgs ? { }
, check ? true
@ -18,32 +10,13 @@ let
_file = ./eval-config.nix;
config = {
_module.args = {
inherit baseModules inputs modules;
inherit baseModules modules;
};
};
};
pkgsModule = { config, inputs, ... }: {
_file = ./eval-config.nix;
config = {
assertions = [ {
# Ensure that nixpkgs.* options are not set when pkgs is set
assertion = pkgs == null || (config.nixpkgs.config == { } && config.nixpkgs.overlays == [ ]);
message = ''
`nixpkgs` options are disabled when `pkgs` is supplied through `darwinSystem`.
'';
} ];
_module.args.pkgs = if pkgs != null then pkgs else import inputs.nixpkgs config.nixpkgs;
# This permits the configuration to override the passed-in
# system.
nixpkgs.system = lib.mkDefault system;
};
};
eval = lib.evalModules (builtins.removeAttrs args [ "lib" "inputs" "pkgs" "system" ] // {
modules = modules ++ [ argsModule pkgsModule ] ++ baseModules;
eval = lib.evalModules (builtins.removeAttrs args [ "lib" ] // {
modules = modules ++ [ argsModule ] ++ baseModules;
specialArgs = { modulesPath = builtins.toString ./modules; } // specialArgs;
});
in

View file

@ -4,22 +4,36 @@
outputs = { self, nixpkgs }: {
lib = {
# TODO handle multiple architectures.
evalConfig = import ./eval-config.nix { inherit (nixpkgs) lib; };
evalConfig = import ./eval-config.nix;
darwinSystem =
{ modules, inputs ? { }
, system ? throw "darwin.lib.darwinSystem now requires 'system' to be passed explicitly"
, ...
}@args:
self.lib.evalConfig (args // {
inherit system;
inputs = { inherit nixpkgs; darwin = self; } // inputs;
modules = modules ++ [ self.darwinModules.flakeOverrides ];
});
darwinSystem = args@{ modules, ... }: self.lib.evalConfig (
{ inherit (nixpkgs) lib; }
// nixpkgs.lib.optionalAttrs (args ? pkgs) { inherit (args.pkgs) lib; }
// builtins.removeAttrs args [ "system" "pkgs" "inputs" ]
// {
modules = modules
++ nixpkgs.lib.optional (args ? pkgs) ({ lib, ... }: {
_module.args.pkgs = lib.mkForce args.pkgs;
})
# Backwards compatibility shim; TODO: warn?
++ nixpkgs.lib.optional (args ? system) ({ lib, ... }: {
nixpkgs.system = lib.mkDefault args.system;
})
# Backwards compatibility shim; TODO: warn?
++ nixpkgs.lib.optional (args ? inputs) {
_module.args.inputs = args.inputs;
}
++ [ ({ lib, ... }: {
nixpkgs.source = lib.mkDefault nixpkgs;
system.checks.verifyNixPath = lib.mkDefault false;
system.darwinVersionSuffix = ".${self.shortRev or "dirty"}";
system.darwinRevision = lib.mkIf (self ? rev) self.rev;
}) ];
});
};
darwinModules.flakeOverrides = ./modules/system/flake-overrides.nix;
darwinModules.hydra = ./modules/examples/hydra.nix;
darwinModules.lnl = ./modules/examples/lnl.nix;
darwinModules.ofborg = ./modules/examples/ofborg.nix;
@ -32,8 +46,10 @@
checks = nixpkgs.lib.genAttrs ["aarch64-darwin" "x86_64-darwin"] (system: let
simple = self.lib.darwinSystem {
inherit system;
modules = [ self.darwinModules.simple ];
modules = [
self.darwinModules.simple
{ nixpkgs.hostPlatform = system; }
];
};
in {
simple = simple.system;

View file

@ -1,4 +1,4 @@
toplevel@{ config, lib, pkgs, baseModules, modules, ... }:
{ config, lib, pkgs, baseModules, modules, ... }:
with lib;
@ -25,15 +25,7 @@ let
inherit pkgs config;
version = config.system.darwinVersion;
revision = config.system.darwinRevision;
nixpkgsRevision =
if toplevel.options.system.nixpkgsRevision.isDefined
then config.system.nixpkgsRevision
# If user does not use flakes and does not add rev to nixpkgs, we don't
# know which revision or even branch they're on. In this case we still want
# to link somewhere, so we hope that master hasn't changed too much.
else "master";
inherit (config.system) nixpkgsRevision;
options =
let
scrubbedEval = evalModules {
@ -54,7 +46,7 @@ let
# TODO: Remove this when dropping 22.11 support.
manual = realManual //
lib.optionalAttrs (lib.versionOlder lib.version "23.05-pre") rec {
lib.optionalAttrs (!pkgs.buildPackages ? nixos-render-docs) rec {
optionsJSON = pkgs.writeTextFile {
name = "options.json-stub";
destination = "/share/doc/darwin/options.json";

View file

@ -1,9 +1,9 @@
{
description = "Example darwin system flake";
description = "Example Darwin system flake";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs";
darwin.url = "github:lnl7/nix-darwin";
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
darwin.url = "github:LnL7/nix-darwin";
darwin.inputs.nixpkgs.follows = "nixpkgs";
};
@ -30,6 +30,9 @@
# Used for backwards compatibility, please read the changelog before changing.
# $ darwin-rebuild changelog
system.stateVersion = 4;
# The platform the configuration will be used on.
nixpkgs.hostPlatform = "x86_64-darwin";
};
in
{
@ -37,7 +40,6 @@
# $ darwin-rebuild build --flake .#simple
darwinConfigurations."simple" = darwin.lib.darwinSystem {
modules = [ configuration ];
system = "x86_64-darwin";
};
# Expose the package set, including overlays, for convenience.

View file

@ -1,8 +1,53 @@
{ config, lib, pkgs, ... }:
{ config, options, lib, pkgs, ... }:
with lib;
let
# Backport from Nixpkgs 23.05
defaultOverridePriority =
lib.modules.defaultOverridePriority or lib.modules.defaultPriority;
# Backport from Nixpkgs 23.11
mergeAttrDefinitionsWithPrio = lib.mergeAttrDefinitionsWithPrio or (opt:
let
# Inlined to avoid warning about using internal APIs 🥴
pushDownProperties = cfg:
if cfg._type or "" == "merge" then
concatMap pushDownProperties cfg.contents
else if cfg._type or "" == "if" then
map (mapAttrs (n: v: mkIf cfg.condition v)) (pushDownProperties cfg.content)
else if cfg._type or "" == "override" then
map (mapAttrs (n: v: mkOverride cfg.priority v)) (pushDownProperties cfg.content)
else # FIXME: handle mkOrder?
[ cfg ];
defsByAttr =
lib.zipAttrs (
lib.concatLists (
lib.concatMap
({ value, ... }@def:
map
(lib.mapAttrsToList (k: value: { ${k} = def // { inherit value; }; }))
(pushDownProperties value)
)
opt.definitionsWithLocations
)
);
in
assert opt.type.name == "attrsOf" || opt.type.name == "lazyAttrsOf";
lib.mapAttrs
(k: v:
let merging = lib.mergeDefinitions (opt.loc ++ [k]) opt.type.nestedTypes.elemType v;
in {
value = merging.mergedValue;
inherit (merging.defsFinal') highestPrio;
})
defsByAttr);
cfg = config.nixpkgs;
opt = options.nixpkgs;
isConfig = x:
builtins.isAttrs x || lib.isFunction x;
@ -16,26 +61,27 @@ let
lhs = optCall lhs_ { inherit pkgs; };
rhs = optCall rhs_ { inherit pkgs; };
in
lhs // rhs //
recursiveUpdate lhs rhs //
optionalAttrs (lhs ? packageOverrides) {
packageOverrides = pkgs:
optCall lhs.packageOverrides pkgs //
optCall (attrByPath ["packageOverrides"] ({}) rhs) pkgs;
optCall (attrByPath [ "packageOverrides" ] { } rhs) pkgs;
} //
optionalAttrs (lhs ? perlPackageOverrides) {
perlPackageOverrides = pkgs:
optCall lhs.perlPackageOverrides pkgs //
optCall (attrByPath ["perlPackageOverrides"] ({}) rhs) pkgs;
optCall (attrByPath [ "perlPackageOverrides" ] { } rhs) pkgs;
};
configType = mkOptionType {
name = "nixpkgs config";
name = "nixpkgs-config";
description = "nixpkgs config";
check = x:
let traceXIfNot = c:
if c x then true
else lib.traceSeqN 1 x false;
in traceXIfNot isConfig;
merge = args: fold (def: mergeConfig def.value) {};
merge = args: foldr (def: mergeConfig def.value) {};
};
overlayType = mkOptionType {
@ -44,72 +90,260 @@ let
check = lib.isFunction;
merge = lib.mergeOneOption;
};
# TODO: Remove backwards compatibility hack when dropping
# 22.11 support.
pkgsType = types.pkgs or (types.uniq types.attrs) // {
# This type is only used by itself, so let's elaborate the description a bit
# for the purpose of documentation.
description = "An evaluation of Nixpkgs; the top level attribute set of packages";
};
hasBuildPlatform = opt.buildPlatform.highestPrio < (mkOptionDefault {}).priority;
hasHostPlatform = opt.hostPlatform.isDefined;
hasPlatform = hasHostPlatform || hasBuildPlatform;
# Context for messages
hostPlatformLine = optionalString hasHostPlatform "${showOptionWithDefLocs opt.hostPlatform}";
buildPlatformLine = optionalString hasBuildPlatform "${showOptionWithDefLocs opt.buildPlatform}";
legacyOptionsDefined =
optional (opt.system.highestPrio < (mkDefault {}).priority) opt.system
;
defaultPkgs =
if opt.hostPlatform.isDefined
then
let isCross = cfg.buildPlatform != cfg.hostPlatform;
systemArgs =
if isCross
then {
localSystem = cfg.buildPlatform;
crossSystem = cfg.hostPlatform;
}
else {
localSystem = cfg.hostPlatform;
};
in
import cfg.source ({
inherit (cfg) config overlays;
} // systemArgs)
else
import cfg.source {
inherit (cfg) config overlays;
localSystem = { inherit (cfg) system; };
};
finalPkgs = if opt.pkgs.isDefined then cfg.pkgs.appendOverlays cfg.overlays else defaultPkgs;
in
{
options = {
nixpkgs.config = mkOption {
options.nixpkgs = {
pkgs = mkOption {
type = pkgsType;
example = literalExpression "import <nixpkgs> {}";
description = lib.mdDoc ''
If set, the pkgs argument to all nix-darwin modules is the value of
this option, extended with `nixpkgs.overlays`, if
that is also set. The nix-darwin and Nixpkgs architectures must
match. Any other options in `nixpkgs.*`, notably `config`,
will be ignored.
The default value imports the Nixpkgs from
[](#opt-nixpkgs.source). The `config`, `overlays`, `localSystem`,
and `crossSystem` are based on this option's siblings.
This option can be used to increase
the performance of evaluation, or to create packages that depend
on a container that should be built with the exact same evaluation
of Nixpkgs, for example. Applications like this should set
their default value using `lib.mkDefault`, so
user-provided configuration can override it without using
`lib`.
'';
};
config = mkOption {
default = {};
example = literalExpression
''
{ firefox.enableGeckoMediaPlayer = true;
packageOverrides = pkgs: {
firefox60Pkgs = pkgs.firefox60Pkgs.override {
enableOfficialBranding = true;
};
};
}
{ allowBroken = true; allowUnfree = true; }
'';
type = configType;
description = lib.mdDoc ''
The configuration of the Nix Packages collection. (For
details, see the Nixpkgs documentation.) It allows you to set
package configuration options, and to override packages
globally through the {var}`packageOverrides`
option. The latter is a function that takes as an argument
the *original* Nixpkgs, and must evaluate
to a set of new or overridden packages.
package configuration options.
Ignored when `nixpkgs.pkgs` is set.
'';
};
nixpkgs.overlays = mkOption {
type = types.listOf overlayType;
overlays = mkOption {
default = [];
example = literalExpression ''
[ (self: super: {
openssh = super.openssh.override {
hpnSupport = true;
withKerberos = true;
kerberos = self.libkrb5;
};
};
) ]
'';
example = literalExpression
''
[
(self: super: {
openssh = super.openssh.override {
hpnSupport = true;
kerberos = self.libkrb5;
};
})
]
'';
type = types.listOf overlayType;
description = lib.mdDoc ''
List of overlays to use with the Nix Packages collection.
(For details, see the Nixpkgs documentation.) It allows
you to override packages globally. This is a function that
you to override packages globally. Each function in the list
takes as an argument the *original* Nixpkgs.
The first argument should be used for finding dependencies, and
the second should be used for overriding recipes.
If `nixpkgs.pkgs` is set, overlays specified here
will be applied after the overlays that were already present
in `nixpkgs.pkgs`.
'';
};
nixpkgs.system = mkOption {
hostPlatform = mkOption {
type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform
example = { system = "aarch64-darwin"; config = "aarch64-apple-darwin"; };
# Make sure that the final value has all fields for sake of other modules
# referring to this. TODO make `lib.systems` itself use the module system.
apply = lib.systems.elaborate;
description = lib.mdDoc ''
Specifies the platform where the nix-darwin configuration will run.
To cross-compile, set also `nixpkgs.buildPlatform`.
Ignored when `nixpkgs.pkgs` is set.
'';
};
buildPlatform = mkOption {
type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform
default = cfg.hostPlatform;
example = { system = "x86_64-darwin"; config = "x86_64-apple-darwin"; };
# Make sure that the final value has all fields for sake of other modules
# referring to this.
apply = lib.systems.elaborate;
defaultText = literalExpression
''config.nixpkgs.hostPlatform'';
description = lib.mdDoc ''
Specifies the platform on which nix-darwin should be built.
By default, nix-darwin is built on the system where it runs, but you can
change where it's built. Setting this option will cause nix-darwin to be
cross-compiled.
For instance, if you're doing distributed multi-platform deployment,
or if you're building machines, you can set this to match your
development system and/or build farm.
Ignored when `nixpkgs.pkgs` is set.
'';
};
system = mkOption {
type = types.str;
example = "x86_64-darwin";
default =
if opt.hostPlatform.isDefined
then
throw ''
Neither ${opt.system} nor any other option in nixpkgs.* is meant
to be read by modules and configurations.
Use pkgs.stdenv.hostPlatform instead.
''
else
throw ''
Neither ${opt.hostPlatform} nor the legacy option ${opt.system} has been set.
The option ${opt.system} is still fully supported for interoperability,
but will be deprecated in the future, so we recommend to set ${opt.hostPlatform}.
'';
defaultText = lib.literalMD ''
Traditionally `builtins.currentSystem`, but unset when invoking nix-darwin through `lib.darwinSystem`.
'';
description = lib.mdDoc ''
Specifies the Nix platform type for which NixOS should be built.
If unset, it defaults to the platform type of your host system.
Specifying this option is useful when doing distributed
multi-platform deployment, or when building virtual machines.
Specifies the Nix platform type on which nix-darwin should be built.
It is better to specify `nixpkgs.hostPlatform` instead.
Ignored when `nixpkgs.pkgs` or `nixpkgs.hostPlatform` is set.
'';
};
# nix-darwin only
source = mkOption {
type = types.path;
defaultText = literalMD ''
`<nixpkgs>` or nix-darwin's `nixpkgs` flake input
'';
description = lib.mdDoc ''
The path to import Nixpkgs from. If you're setting a custom
[](#opt-nixpkgs.pkgs) or `_module.args.pkgs`, setting this
to something with `rev` and `shortRev` attributes (such as a
flake input or `builtins.fetchGit` result) will also set
`system.nixpkgsRevision` and related options.
(nix-darwin only)
'';
};
constructedByUs = mkOption {
type = types.bool;
internal = true;
description = ''
Whether `pkgs` was constructed by this module. This is false when any of
`nixpkgs.pkgs` or `_module.args.pkgs` is set. (nix-darwin only)
'';
};
};
config = {
_module.args = {
pkgs =
# We explicitly set the default override priority, so that we do not need
# to evaluate finalPkgs in case an override is placed on `_module.args.pkgs`.
# After all, to determine a definition priority, we need to evaluate `._type`,
# which is somewhat costly for Nixpkgs. With an explicit priority, we only
# evaluate the wrapper to find out that the priority is lower, and then we
# don't need to evaluate `finalPkgs`.
lib.mkOverride defaultOverridePriority
finalPkgs.__splicedPackages;
};
# _module.args.pkgs is defined in ../../eval-config.nix
nixpkgs.constructedByUs =
# We set it with default priority and it can not be merged, so if the
# pkgs module argument has that priority, it's from us.
(mergeAttrDefinitionsWithPrio options._module.args).pkgs.highestPrio
== defaultOverridePriority
# Although, if nixpkgs.pkgs is set, we did forward it, but we did not construct it.
&& !opt.pkgs.isDefined;
assertions = [
(
let
pkgsSystem = finalPkgs.stdenv.targetPlatform.system;
in {
assertion = cfg.constructedByUs -> !hasPlatform -> cfg.system == pkgsSystem;
message = "The nix-darwin nixpkgs.pkgs option was set to a Nixpkgs invocation that compiles to target system ${pkgsSystem} but nix-darwin was configured for system ${darwinExpectedSystem} via nix-darwin option nixpkgs.system. The nix-darwin system settings must match the Nixpkgs target system.";
}
)
{
assertion = cfg.constructedByUs -> hasPlatform -> legacyOptionsDefined == [];
message = ''
Your system configures nixpkgs with the platform parameter${optionalString hasBuildPlatform "s"}:
${hostPlatformLine
}${buildPlatformLine
}
However, it also defines the legacy options:
${concatMapStrings showOptionWithDefLocs legacyOptionsDefined}
For a future proof system configuration, we recommend to remove
the legacy definitions.
'';
}
];
};
}

View file

@ -1,20 +0,0 @@
{ lib, inputs, ... }:
with lib;
let
inherit (inputs) darwin nixpkgs;
in
{
config = {
system.checks.verifyNixPath = mkDefault false;
system.checks.verifyNixChannels = mkDefault false;
system.darwinVersionSuffix = ".${darwin.shortRev or "dirty"}";
system.darwinRevision = mkIf (darwin ? rev) darwin.rev;
system.nixpkgsVersionSuffix = ".${substring 0 8 (nixpkgs.lastModifiedDate or nixpkgs.lastModified or "19700101")}.${nixpkgs.shortRev or "dirty"}";
system.nixpkgsRevision = mkIf (nixpkgs ? rev) nixpkgs.rev;
};
}

View file

@ -1,4 +1,4 @@
{ options, config, lib, pkgs, ... }:
{ options, config, lib, ... }:
with lib;
@ -7,27 +7,28 @@ let
defaultStateVersion = options.system.stateVersion.default;
parseGit = path:
if pathExists "${path}/.git" then rec {
rev = commitIdFromGitRepo "${path}/.git";
shortRev = substring 0 7 rev;
}
else if pathExists "${path}/.git-revision" then rec {
rev = fileContents "${path}/.git-revision";
shortRev = substring 0 7 rev;
}
else {
shortRev = "0000000";
};
# Based on `lib.trivial.revisionWithDefault` from nixpkgs.
gitRevision = path:
if pathIsGitRepo "${path}/.git"
then commitIdFromGitRepo "${path}/.git"
else if pathExists "${path}/.git-revision"
then fileContents "${path}/.git-revision"
else null;
darwin = parseGit (toString ../..);
nixpkgs = parseGit (toString pkgs.path);
nixpkgsSrc = config.nixpkgs.source;
releaseFile = "${toString pkgs.path}/.version";
suffixFile = "${toString pkgs.path}/.version-suffix";
nixpkgsSuffix = if pathExists suffixFile then fileContents suffixFile
else ".git." + nixpkgs.shortRev;
# If `nixpkgs.constructedByUs` is true, then Nixpkgs was imported from
# `nixpkgs.source` and we can use revision information (flake input,
# `builtins.fetchGit`, etc.) from it. Otherwise `pkgs` could be
# anything and we can't reliably determine exact version information,
# but if the configuration explicitly sets `nixpkgs.source` we
# trust it.
useSourceRevision =
(config.nixpkgs.constructedByUs
|| options.nixpkgs.source.highestPrio < (lib.mkDefault {}).priority)
&& isAttrs nixpkgsSrc
&& (nixpkgsSrc._type or null == "flake"
|| isString (nixpkgsSrc.rev or null));
in
{
@ -56,62 +57,67 @@ in
system.darwinVersion = mkOption {
internal = true;
type = types.str;
description = lib.mdDoc "The full darwin version (e.g. `darwin4.master`).";
default = "darwin${toString cfg.stateVersion}${cfg.darwinVersionSuffix}";
description = lib.mdDoc "The full darwin version (e.g. `darwin4.2abdb5a`).";
};
system.darwinVersionSuffix = mkOption {
internal = true;
type = types.str;
default = if cfg.darwinRevision != null
then ".${substring 0 7 cfg.darwinRevision}"
else "";
description = lib.mdDoc "The short darwin version suffix (e.g. `.2abdb5a`).";
};
system.darwinRevision = mkOption {
internal = true;
type = types.str;
default = "master";
type = types.nullOr types.str;
default = gitRevision (toString ../..);
description = lib.mdDoc "The darwin git revision from which this configuration was built.";
};
system.nixpkgsRelease = mkOption {
readOnly = true;
type = types.str;
default = lib.trivial.release;
description = lib.mdDoc "The nixpkgs release (e.g. `16.03`).";
};
system.nixpkgsVersion = mkOption {
internal = true;
type = types.str;
default = cfg.nixpkgsRelease + cfg.nixpkgsVersionSuffix;
description = lib.mdDoc "The full nixpkgs version (e.g. `16.03.1160.f2d4ee1`).";
};
system.nixpkgsVersionSuffix = mkOption {
internal = true;
type = types.str;
default = if useSourceRevision
then ".${lib.substring 0 8 (nixpkgsSrc.lastModifiedDate or nixpkgsSrc.lastModified or "19700101")}.${nixpkgsSrc.shortRev or "dirty"}"
else lib.trivial.versionSuffix;
description = lib.mdDoc "The short nixpkgs version suffix (e.g. `.1160.f2d4ee1`).";
};
system.nixpkgsRevision = mkOption {
internal = true;
type = types.str;
type = types.nullOr types.str;
default = if useSourceRevision && nixpkgsSrc ? rev
then nixpkgsSrc.rev
else lib.trivial.revisionWithDefault null;
description = lib.mdDoc "The nixpkgs git revision from which this configuration was built.";
};
};
config = {
# These defaults are set here rather than up there so that
# changing them would not rebuild the manual
# This default is set here rather than up there so that the options
# documentation is not reprocessed on every commit
system.darwinLabel = mkDefault "${cfg.nixpkgsVersion}+${cfg.darwinVersion}";
system.darwinVersion = mkDefault "darwin${toString cfg.stateVersion}${cfg.darwinVersionSuffix}";
system.darwinVersionSuffix = mkDefault ".${darwin.shortRev}";
system.darwinRevision = mkIf (darwin ? rev) (mkDefault darwin.rev);
system.nixpkgsVersion = mkDefault "${cfg.nixpkgsRelease}${cfg.nixpkgsVersionSuffix}";
system.nixpkgsRelease = mkDefault (fileContents releaseFile);
system.nixpkgsVersionSuffix = mkDefault nixpkgsSuffix;
system.nixpkgsRevision = mkIf (nixpkgs ? rev) (mkDefault nixpkgs.rev);
assertions = [ { assertion = cfg.stateVersion <= defaultStateVersion; message = "system.stateVersion = ${toString cfg.stateVersion}; is not a valid value"; } ];
assertions = [ {
assertion = cfg.stateVersion <= defaultStateVersion;
message = "system.stateVersion = ${toString cfg.stateVersion}; is not a valid value";
} ];
};
}