Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nixos/modules/installer/tools/tools.nix
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ let
manPage = ./manpages/nixos-version.8;
};

nixos-install = pkgs.nixos-install.override { nix = config.nix.package; };
nixos-install = pkgs.nixos-install.override { };
nixos-rebuild = pkgs.nixos-rebuild.override { nix = config.nix.package; };

defaultConfigTemplate = ''
Expand Down
86 changes: 0 additions & 86 deletions pkgs/build-support/replace-vars/default.nix

This file was deleted.

131 changes: 131 additions & 0 deletions pkgs/build-support/replace-vars/replace-vars-with.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
{ lib, stdenvNoCC }:

/**
`replaceVarsWith` is a wrapper around the [bash function `substitute`](https://nixos.org/manual/nixpkgs/stable/#fun-substitute)
in the stdenv. It allows for terse replacement of names in the specified path, while checking
for common mistakes such as naming a replacement that does nothing or forgetting a variable which
needs to be replaced.

As with the [`--subst-var-by`](https://nixos.org/manual/nixpkgs/stable/#fun-substitute-subst-var-by)
flag, names are encoded as `@name@` in the provided file at the provided path.

Any unmatched variable names in the file at the provided path will cause a build failure.

By default, any remaining text that matches `@[A-Za-z_][0-9A-Za-z_'-]@` in the output after replacement
has occurred will cause a build failure. Variables can be excluded from this check by passing "null" for them.

# Inputs

`src` ([Store Path](https://nixos.org/manual/nix/latest/store/store-path.html#store-path) String)
: The file in which to replace variables.

`replacements` (AttrsOf String)
: Each entry in this set corresponds to a `--subst-var-by` entry in [`substitute`](https://nixos.org/manual/nixpkgs/stable/#fun-substitute) or
null to keep it unchanged.

`dir` (String)
: Sub directory in $out to store the result in. Commonly set to "bin".

`isExecutable` (Boolean)
: Whether to mark the output file as executable.

Most arguments supported by mkDerivation are also supported, with some exceptions for which
an error will be thrown.

# Example

```nix
{ replaceVarsWith }:

replaceVarsWith {
src = ./my-setup-hook.sh;
replacements = { world = "hello"; };
dir = "bin";
isExecutable = true;
}
```

See `../../test/replace-vars/default.nix` for tests of this function. Also see `replaceVars` for a short
version with src and replacements only.
*/
{
src,
replacements,
dir ? null,
isExecutable ? false,
...
}@attrs:

let
# We use `--replace-fail` instead of `--subst-var-by` so that if the thing isn't there, we fail.
subst-var-by =
name: value:
lib.optionals (value != null) [
"--replace-fail"
(lib.escapeShellArg "@${name}@")
(lib.escapeShellArg value)
];

substitutions = lib.concatLists (lib.mapAttrsToList subst-var-by replacements);

left-overs = map ({ name, ... }: name) (
builtins.filter ({ value, ... }: value == null) (lib.attrsToList replacements)
);

optionalAttrs =
if (builtins.intersectAttrs attrs forcedAttrs == { }) then
builtins.removeAttrs attrs [ "replacements" ]
else
throw "Passing any of ${builtins.concatStringsSep ", " (builtins.attrNames forcedAttrs)} to replaceVarsWith is not supported.";

forcedAttrs = {
doCheck = true;
dontUnpack = true;
preferLocalBuild = true;
allowSubstitutes = false;

buildPhase = ''
runHook preBuild

target=$out
if test -n "$dir"; then
target=$out/$dir/$name
mkdir -p $out/$dir
fi

substitute "$src" "$target" ${lib.concatStringsSep " " substitutions}

if test -n "$isExecutable"; then
chmod +x $target
fi

runHook postBuild
'';

# Look for Nix identifiers surrounded by `@` that aren't substituted.
checkPhase =
let
lookahead =
if builtins.length left-overs == 0 then "" else "(?!${builtins.concatStringsSep "|" left-overs}@)";
regex = lib.escapeShellArg "@${lookahead}[a-zA-Z_][0-9A-Za-z_'-]*@";
in
''
runHook preCheck
if grep -Pqe ${regex} "$out"; then
echo The following look like unsubstituted Nix identifiers that remain in "$out":
grep -Poe ${regex} "$out"
echo Use the more precise '`substitute`' function if this check is in error.
exit 1
fi
runHook postCheck
'';
};
in

stdenvNoCC.mkDerivation (
{
name = baseNameOf (toString src);
}
// optionalAttrs
// forcedAttrs
)
36 changes: 36 additions & 0 deletions pkgs/build-support/replace-vars/replace-vars.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{ replaceVarsWith }:

/**
`replaceVars` is a wrapper around the [bash function `substitute`](https://nixos.org/manual/nixpkgs/stable/#fun-substitute)
in the stdenv. It allows for terse replacement of names in the specified path, while checking
for common mistakes such as naming a replacement that does nothing or forgetting a variable which
needs to be replaced.

As with the [`--subst-var-by`](https://nixos.org/manual/nixpkgs/stable/#fun-substitute-subst-var-by)
flag, names are encoded as `@name@` in the provided file at the provided path.

Any unmatched variable names in the file at the provided path will cause a build failure.

By default, any remaining text that matches `@[A-Za-z_][0-9A-Za-z_'-]@` in the output after replacement
has occurred will cause a build failure. Variables can be excluded from this check by passing "null" for them.

# Inputs

`src` ([Store Path](https://nixos.org/manual/nix/latest/store/store-path.html#store-path) String)
: The file in which to replace variables.

`replacements` (AttrsOf String)
: Each entry in this set corresponds to a `--subst-var-by` entry in [`substitute`](https://nixos.org/manual/nixpkgs/stable/#fun-substitute) or
null to keep it unchanged.

# Example

```nix
{ replaceVars }:

replaceVars ./greeting.txt { world = "hello"; }
```

See `../../test/replace-vars/default.nix` for tests of this function.
*/
src: replacements: replaceVarsWith { inherit src replacements; }
2 changes: 1 addition & 1 deletion pkgs/by-name/de/deterministic-uname/deterministic-uname.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#! @shell@
#! @runtimeShell@

set -o errexit
set -o nounset
Expand Down
54 changes: 28 additions & 26 deletions pkgs/by-name/de/deterministic-uname/package.nix
Original file line number Diff line number Diff line change
@@ -1,44 +1,46 @@
# expr and script based on our lsb_release
{ stdenv
, lib
, substituteAll
, replaceVarsWith
, coreutils
, getopt
, runtimeShell
, modDirVersion ? ""
, forPlatform ? stdenv.buildPlatform
}:

substituteAll {
replaceVarsWith {
name = "uname";

src = ./deterministic-uname.sh;

dir = "bin";
isExecutable = true;

inherit coreutils getopt;

uSystem = if forPlatform.uname.system != null then forPlatform.uname.system else "unknown";
inherit (forPlatform.uname) processor;

# uname -o
# maybe add to lib/systems/default.nix uname attrset
# https://github.com/coreutils/coreutils/blob/7fc84d1c0f6b35231b0b4577b70aaa26bf548a7c/src/uname.c#L373-L374
# https://stackoverflow.com/questions/61711186/where-does-host-operating-system-in-uname-c-comes-from
# https://github.com/coreutils/gnulib/blob/master/m4/host-os.m4
operatingSystem =
if forPlatform.isLinux
then "GNU/Linux"
else if forPlatform.isDarwin
then "Darwin" # darwin isn't in host-os.m4 so where does this come from?
else if forPlatform.isFreeBSD
then "FreeBSD"
else "unknown";

# in os-specific/linux module packages
# --replace '$(shell uname -r)' "${kernel.modDirVersion}" \
# is a common thing to do.
modDirVersion = if modDirVersion != "" then modDirVersion else "unknown";
replacements = {
inherit coreutils getopt runtimeShell;

uSystem = if forPlatform.uname.system != null then forPlatform.uname.system else "unknown";
inherit (forPlatform.uname) processor;

# uname -o
# maybe add to lib/systems/default.nix uname attrset
# https://github.com/coreutils/coreutils/blob/7fc84d1c0f6b35231b0b4577b70aaa26bf548a7c/src/uname.c#L373-L374
# https://stackoverflow.com/questions/61711186/where-does-host-operating-system-in-uname-c-comes-from
# https://github.com/coreutils/gnulib/blob/master/m4/host-os.m4
operatingSystem =
if forPlatform.isLinux
then "GNU/Linux"
else if forPlatform.isDarwin
then "Darwin" # darwin isn't in host-os.m4 so where does this come from?
else if forPlatform.isFreeBSD
then "FreeBSD"
else "unknown";

# in os-specific/linux module packages
# --replace '$(shell uname -r)' "${kernel.modDirVersion}" \
# is a common thing to do.
modDirVersion = if modDirVersion != "" then modDirVersion else "unknown";
};

meta = with lib; {
description = "Print certain system information (hardcoded with lib/system values)";
Expand Down
40 changes: 21 additions & 19 deletions pkgs/by-name/ls/lsb-release/package.nix
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
{
replaceVars,
runCommand,
replaceVarsWith,
lib,
runtimeShell,
coreutils,
getopt,
}:

runCommand "lsb_release"
{
meta = with lib; {
description = "Prints certain LSB (Linux Standard Base) and Distribution information";
mainProgram = "lsb_release";
license = [ licenses.mit ];
maintainers = with maintainers; [ primeos ];
platforms = platforms.linux;
};
}
''
install -Dm 555 ${
replaceVars ./lsb_release.sh {
inherit runtimeShell coreutils getopt;
}
} $out/bin/lsb_release
''
replaceVarsWith {
name = "lsb_release";

src = ./lsb_release.sh;

dir = "bin";
isExecutable = true;

replacements = {
inherit coreutils getopt runtimeShell;
};

meta = with lib; {
description = "Prints certain LSB (Linux Standard Base) and Distribution information";
mainProgram = "lsb_release";
license = [ licenses.mit ];
maintainers = with maintainers; [ primeos ];
platforms = platforms.linux;
};
}
Loading