resholve: 0.6.9 -> 0.8.0

Also track upstream .nix changes over same window.
This commit is contained in:
Travis A. Everett 2022-04-08 01:45:09 -05:00 committed by Yt
parent 9a83d8ce94
commit 09d441d21c
9 changed files with 302 additions and 218 deletions

View file

@ -1,9 +1,18 @@
# Using resholve's Nix API
resholve replaces bare references (subject to a PATH search at runtime) to external commands and scripts with absolute paths.
resholve converts bare executable references in shell scripts to absolute
paths. This will hopefully make its way into the Nixpkgs manual soon, but
until then I'll outline how to use the `resholvePackage`, `resholveScript`,
and `resholveScriptBin` functions.
This small super-power helps ensure script dependencies are declared, present, and don't unexpectedly shift when the PATH changes.
resholve is developed to enable the Nix package manager to package and integrate Shell projects, but its features are not Nix-specific and inevitably have other applications.
<!-- generated from resholve's repo; best to suggest edits there (or at least notify me) -->
This will hopefully make its way into the Nixpkgs manual soon, but
until then I'll outline how to use the functions:
- `resholve.mkDerivation` (formerly `resholvePackage`)
- `resholve.writeScript` (formerly `resholveScript`)
- `resholve.writeScriptBin` (formerly `resholveScriptBin`)
- `resholve.phraseSolution` (new in resholve 0.8.0)
> Fair warning: resholve does *not* aspire to resolving all valid Shell
> scripts. It depends on the OSH/Oil parser, which aims to support most (but
@ -11,7 +20,7 @@ and `resholveScriptBin` functions.
## API Concepts
The main difference between `resholvePackage` and other builder functions
The main difference between `resholve.mkDerivation` and other builder functions
is the `solutions` attrset, which describes which scripts to resolve and how.
Each "solution" (k=v pair) in this attrset describes one resholve invocation.
@ -22,70 +31,81 @@ Each "solution" (k=v pair) in this attrset describes one resholve invocation.
> - Packages with scripts that require conflicting directives can use multiple
> solutions to resolve the scripts separately, but produce a single package.
The `resholveScript` and `resholveScriptBin` functions support a _single_
`solution` attrset. This is basically the same as any single solution in `resholvePackage`, except that it doesn't need a `scripts` attr (it is automatically added).
`resholve.writeScript` and `resholve.writeScriptBin` support a _single_
`solution` attrset. This is basically the same as any single solution in `resholve.mkDerivation`, except that it doesn't need a `scripts` attr (it is automatically added). `resholve.phraseSolution` also only accepts a single solution--but it _does_ still require the `scripts` attr.
## Basic `resholvePackage` Example
## Basic `resholve.mkDerivation` Example
Here's a simple example from one of my own projects, with annotations:
<!--
TODO: ideally this will use a nixpkgs example; but we don't have any IN yet
and the first package PR (bashup-events) is too complex for this context.
-->
Here's a simple example of how `resholve.mkDerivation` is already used in nixpkgs:
<!-- TODO: figure out how to pull this externally? -->
```nix
{ stdenv, lib, resholvePackage, fetchFromGitHub, bashup-events44, bashInteractive_5, doCheck ? true, shellcheck }:
{ lib
, fetchFromGitHub
, resholve
, substituteAll
, bash
, coreutils
, goss
, which
}:
resholvePackage rec {
pname = "shellswain";
version = "unreleased";
resholve.mkDerivation rec {
pname = "dgoss";
version = "0.3.16";
src = fetchFromGitHub {
# ...
owner = "aelsabbahy";
repo = "goss";
rev = "v${version}";
sha256 = "1m5w5vwmc9knvaihk61848rlq7qgdyylzpcwi64z84rkw8qdnj6p";
};
dontConfigure = true;
dontBuild = true;
installPhase = ''
sed -i '2i GOSS_PATH=${goss}/bin/goss' extras/dgoss/dgoss
install -D extras/dgoss/dgoss $out/bin/dgoss
'';
solutions = {
# Give each solution a short name. This is what you'd use to
# override its settings, and it shows in (some) error messages.
profile = {
# the only *required* arguments are the 3 below
# Specify 1 or more $out-relative script paths. Unlike many
# builders, resholvePackage modifies the output files during
# fixup (to correctly resolve in-package sourcing).
scripts = [ "bin/shellswain.bash" ];
# "none" for no shebang, "${bash}/bin/bash" for bash, etc.
interpreter = "none";
# packages resholve should resolve executables from
inputs = [ bashup-events44 ];
default = {
scripts = [ "bin/dgoss" ];
interpreter = "${bash}/bin/bash";
inputs = [ coreutils which ];
fake = {
external = [ "docker" ];
};
};
};
makeFlags = [ "prefix=${placeholder "out"}" ];
inherit doCheck;
checkInputs = [ shellcheck ];
# ...
meta = with lib; {
homepage = "https://github.com/aelsabbahy/goss/blob/v${version}/extras/dgoss/README.md";
description = "Convenience wrapper around goss that aims to bring the simplicity of goss to docker containers";
license = licenses.asl20;
platforms = platforms.linux;
maintainers = with maintainers; [ hyzual ];
};
}
```
## Basic `resholveScript` and `resholveScriptBin` examples
## Basic `resholve.writeScript` and `resholve.writeScriptBin` examples
Both of these functions have the same basic API. This example is a little
trivial for now. If you have a real usage that you find helpful, please PR it.
```nix
resholvedScript = resholveScript "name" {
resholvedScript = resholve.writeScript "name" {
inputs = [ file ];
interpreter = "${bash}/bin/bash";
} ''
echo "Hello"
file .
'';
resholvedScriptBin = resholveScriptBin "name" {
resholvedScriptBin = resholve.writeScriptBin "name" {
inputs = [ file ];
interpreter = "${bash}/bin/bash";
} ''
@ -94,25 +114,56 @@ resholvedScriptBin = resholveScriptBin "name" {
'';
```
## Basic `resholve.phraseSolution` example
This function has a similar API to `writeScript` and `writeScriptBin`, except it does require a `scripts` attr. It is intended to make resholve a little easier to mix into more types of build. This example is a little
trivial for now. If you have a real usage that you find helpful, please PR it.
```nix
{ stdenv, resholve, module1 }:
stdenv.mkDerivation {
# pname = "testmod3";
# version = "unreleased";
# src = ...;
installPhase = ''
mkdir -p $out/bin
install conjure.sh $out/bin/conjure.sh
${resholve.phraseSolution "conjure" {
scripts = [ "bin/conjure.sh" ];
interpreter = "${bash}/bin/bash";
inputs = [ module1 ];
fake = {
external = [ "jq" "openssl" ];
};
}}
'';
}
```
## Options
`resholvePackage` maps Nix types/idioms into the flags and environment variables
`resholve.mkDerivation` maps Nix types/idioms into the flags and environment variables
that the `resholve` CLI expects. Here's an overview:
| Option | Type | Containing |
| ------------- | ------- | ----------------------------------------------------- |
| scripts | list | $out-relative string paths to resolve |
| inputs | list | packages to resolve executables from |
| interpreter | string | 'none' or abspath for shebang |
| prologue | file | text to insert before the first code-line |
| epilogue | file | text to insert after the last code-line |
| flags | list | strings to pass as flags |
| fake | attrset | [directives](#controlling-resolution-with-directives) |
| fix | attrset | [directives](#controlling-resolution-with-directives) |
| keep | attrset | [directives](#controlling-resolution-with-directives) |
| lore | string | [lore directory](#controlling-nested-resolution-with-lore) |
| execers | list | [execer lore directive](#controlling-nested-resolution-with-lore) |
| wrappers | list | [wrapper lore directive](#controlling-nested-resolution-with-lore) |
| Option | Type | Containing |
|--------|------|------------|
| scripts | `<list>` | scripts to resolve (`$out`-relative paths) |
| interpreter | `"none"` `<path>` | The absolute interpreter `<path>` for the script's shebang. The special value `none` ensures there is no shebang. |
| inputs | `<packages>` | Packages to resolve external dependencies from. |
| fake | `<directives>` | pretend some commands exist |
| fix | `<directives>` | fix things we can't auto-fix/ignore |
| keep | `<directives>` | keep things we can't auto-fix/ignore |
| lore | `<directory>` | control nested resolution |
| execer | `<statements>` | modify nested resolution |
| wrapper | `<statements>` | modify nested resolution |
| prologue | `<file>` | insert file before resolved script |
| epilogue | `<file>` | insert file after resolved script |
<!-- TODO: section below is largely custom for nixpkgs, but I would LIKE to wurst it. -->
## Controlling resolution with directives
@ -184,6 +235,7 @@ keep = {
};
```
> **Note:** For now, at least, you'll need to reference the manpage to completely understand these examples.
## Controlling nested resolution with lore
@ -213,7 +265,7 @@ There will be more mechanisms for controlling this process in the future
the main lever is the ability to substitute your own lore. This is how you'd
do it piecemeal:
```
```nix
# --execer 'cannot:${openssl.bin}/bin/openssl can:${openssl.bin}/bin/c_rehash'
execer = [
/*
@ -237,5 +289,6 @@ execer = [
];
```
The format is fairly simple to generate--you can script your own generator if
you need to modify the lore.

View file

@ -1,5 +1,5 @@
{ callPackage
, writeTextFile
, ...
}:
let
@ -7,47 +7,15 @@ let
deps = callPackage ./deps.nix { };
in
rec {
# resholve itself
resholve = callPackage ./resholve.nix {
inherit (source) rSrc version;
inherit (deps.oil) oildev;
inherit resholve-utils;
};
# funcs to validate and phrase invocations of resholve
# and use those invocations to build packages
resholve-utils = callPackage ./resholve-utils.nix {
inherit resholve;
};
resholvePackage = callPackage ./resholve-package.nix {
inherit resholve resholve-utils;
};
resholveScript = name: partialSolution: text:
writeTextFile {
inherit name text;
executable = true;
checkPhase = ''
(
PS4=$'\x1f'"\033[33m[resholve context]\033[0m "
set -x
${resholve-utils.makeInvocation name (partialSolution // {
scripts = [ "${placeholder "out"}" ];
})}
)
${partialSolution.interpreter} -n $out
'';
};
resholveScriptBin = name: partialSolution: text:
writeTextFile rec {
inherit name text;
executable = true;
destination = "/bin/${name}";
checkPhase = ''
(
cd "$out"
PS4=$'\x1f'"\033[33m[resholve context]\033[0m "
set -x
: changing directory to $PWD
${resholve-utils.makeInvocation name (partialSolution // {
scripts = [ "bin/${name}" ];
})}
)
${partialSolution.interpreter} -n $out/bin/${name}
'';
};
}

View file

@ -1,37 +0,0 @@
{ stdenv, lib, resholve, resholve-utils }:
{ pname
, src
, version
, passthru ? { }
, solutions
, ...
}@attrs:
let
inherit stdenv;
self = (stdenv.mkDerivation ((removeAttrs attrs [ "solutions" ])
// {
inherit pname version src;
buildInputs = (lib.optionals (builtins.hasAttr "buildInputs" attrs) attrs.buildInputs) ++ [ resholve ];
# enable below for verbose debug info if needed
# supports default python.logging levels
# LOGLEVEL="INFO";
/*
subshell/PS4/set -x and : command to output resholve envs
and invocation. Extra context makes it clearer what the
Nix API is doing, makes nix-shell debugging easier, etc.
*/
preFixup = ''
(
cd "$out"
PS4=$'\x1f'"\033[33m[resholve context]\033[0m "
set -x
: changing directory to $PWD
${builtins.concatStringsSep "\n" (resholve-utils.makeCommands solutions)}
)
'';
}));
in
lib.extendDerivation true passthru self

View file

@ -1,4 +1,4 @@
{ lib, resholve, binlore }:
{ lib, stdenv, resholve, binlore, writeTextFile }:
rec {
/* These functions break up the work of partially validating the
@ -10,6 +10,7 @@ rec {
# for brevity / line length
spaces = l: builtins.concatStringsSep " " l;
colons = l: builtins.concatStringsSep ":" l;
semicolons = l: builtins.concatStringsSep ";" l;
/* Throw a fit with dotted attr path context */
@ -17,58 +18,186 @@ rec {
throw "${builtins.concatStringsSep "." path}: ${msg}";
/* Special-case directive value representations by type */
makeDirective = solution: env: name: val:
phraseDirective = solution: env: name: val:
if builtins.isInt val then builtins.toString val
else if builtins.isString val then name
else if true == val then name
else if false == val then "" # omit!
else if null == val then "" # omit!
else if builtins.isList val then "${name}:${semicolons val}"
else if builtins.isList val then "${name}:${semicolons (map lib.escapeShellArg val)}"
else nope [ solution env name ] "unexpected type: ${builtins.typeOf val}";
/* Build fake/fix/keep directives from Nix types */
makeDirectives = solution: env: val:
lib.mapAttrsToList (makeDirective solution env) val;
phraseDirectives = solution: env: val:
lib.mapAttrsToList (phraseDirective solution env) val;
/* Custom ~search-path routine to handle relative path strings */
relSafeBinPath = input:
if lib.isDerivation input then ((lib.getOutput "bin" input) + "/bin")
else if builtins.isString input then input
else throw "unexpected type for input: ${builtins.typeOf input}";
/* Special-case value representation by type/name */
makeEnvVal = solution: env: val:
if env == "inputs" then lib.makeBinPath val
phraseEnvVal = solution: env: val:
if env == "inputs" then (colons (map relSafeBinPath val))
else if builtins.isString val then val
else if builtins.isList val then spaces val
else if builtins.isAttrs val then spaces (makeDirectives solution env val)
else if builtins.isAttrs val then spaces (phraseDirectives solution env val)
else nope [ solution env ] "unexpected type: ${builtins.typeOf val}";
/* Shell-format each env value */
shellEnv = solution: env: value:
lib.escapeShellArg (makeEnvVal solution env value);
lib.escapeShellArg (phraseEnvVal solution env value);
/* Build a single ENV=val pair */
makeEnv = solution: env: value:
phraseEnv = solution: env: value:
"RESHOLVE_${lib.toUpper env}=${shellEnv solution env value}";
/* Discard attrs claimed by makeArgs */
removeCliArgs = value:
removeAttrs value [ "scripts" "flags" ];
/* Discard attrs:
- claimed by phraseArgs
- only needed for binlore.collect
*/
removeUnneededArgs = value:
removeAttrs value [ "scripts" "flags" "unresholved" ];
/* Verify required arguments are present */
validateSolution = { scripts, inputs, interpreter, ... }: true;
/* Pull out specific solution keys to build ENV=val pairs */
makeEnvs = solution: value:
spaces (lib.mapAttrsToList (makeEnv solution) (removeCliArgs value));
phraseEnvs = solution: value:
spaces (lib.mapAttrsToList (phraseEnv solution) (removeUnneededArgs value));
/* Pull out specific solution keys to build CLI argstring */
makeArgs = { flags ? [ ], scripts, ... }:
phraseArgs = { flags ? [ ], scripts, ... }:
spaces (flags ++ scripts);
phraseBinloreArgs = value:
let
hasUnresholved = builtins.hasAttr "unresholved" value;
in {
drvs = value.inputs ++
lib.optionals hasUnresholved [ value.unresholved ];
strip = if hasUnresholved then [ value.unresholved ] else [ ];
};
/* Build a single resholve invocation */
makeInvocation = solution: value:
phraseInvocation = solution: value:
if validateSolution value then
# we pass resholve a directory
"RESHOLVE_LORE=${binlore.collect { drvs = value.inputs; } } ${makeEnvs solution value} ${resholve}/bin/resholve --overwrite ${makeArgs value}"
"RESHOLVE_LORE=${binlore.collect (phraseBinloreArgs value) } ${phraseEnvs solution value} ${resholve}/bin/resholve --overwrite ${phraseArgs value}"
else throw "invalid solution"; # shouldn't trigger for now
injectUnresholved = solutions: unresholved: (builtins.mapAttrs (name: value: value // { inherit unresholved; } ) solutions);
/* Build resholve invocation for each solution. */
makeCommands = solutions:
lib.mapAttrsToList makeInvocation solutions;
phraseCommands = solutions: unresholved:
builtins.concatStringsSep "\n" (
lib.mapAttrsToList phraseInvocation (injectUnresholved solutions unresholved)
);
/*
subshell/PS4/set -x and : command to output resholve envs
and invocation. Extra context makes it clearer what the
Nix API is doing, makes nix-shell debugging easier, etc.
*/
phraseContext = { invokable, prep ? ''cd "$out"'' }: ''
(
${prep}
PS4=$'\x1f'"\033[33m[resholve context]\033[0m "
set -x
: invoking resholve with PWD=$PWD
${invokable}
)
'';
phraseContextForPWD = invokable: phraseContext { inherit invokable; prep = ""; };
phraseContextForOut = invokable: phraseContext { inherit invokable; };
phraseSolution = name: solution: (phraseContextForOut (phraseInvocation name solution));
phraseSolutions = solutions: unresholved:
phraseContextForOut (phraseCommands solutions unresholved);
writeScript = name: partialSolution: text:
writeTextFile {
inherit name text;
executable = true;
checkPhase = ''
${(phraseContextForPWD (
phraseInvocation name (
partialSolution // {
scripts = [ "${placeholder "out"}" ];
}
)
)
)}
${partialSolution.interpreter} -n $out
'';
};
writeScriptBin = name: partialSolution: text:
writeTextFile rec {
inherit name text;
executable = true;
destination = "/bin/${name}";
checkPhase = ''
${phraseContextForOut (
phraseInvocation name (
partialSolution // {
scripts = [ "bin/${name}" ];
}
)
)
}
${partialSolution.interpreter} -n $out/bin/${name}
'';
};
mkDerivation = { pname
, src
, version
, passthru ? { }
, solutions
, ...
}@attrs:
let
inherit stdenv;
/*
Knock out our special solutions arg, but otherwise
just build what the caller is giving us. We'll
actually resholve it separately below (after we
generate binlore for it).
*/
unresholved = (stdenv.mkDerivation ((removeAttrs attrs [ "solutions" ])
// {
inherit pname version src;
}));
in
/*
resholve in a separate derivation; some concerns:
- we aren't keeping many of the user's args, so they
can't readily set LOGLEVEL and such...
- not sure how this affects multiple outputs
*/
lib.extendDerivation true passthru (stdenv.mkDerivation {
src = unresholved;
version = unresholved.version;
pname = "resholved-${unresholved.pname}";
buildInputs = [ resholve ];
# retain a reference to the base
passthru = unresholved.passthru // {
unresholved = unresholved;
};
# do these imply that we should use NoCC or something?
dontConfigure = true;
dontBuild = true;
installPhase = ''
cp -R $src $out
'';
# enable below for verbose debug info if needed
# supports default python.logging levels
# LOGLEVEL="INFO";
preFixup = phraseSolutions solutions unresholved;
});
}

View file

@ -7,14 +7,13 @@
, version
, oildev
, binlore
, resholve-utils
}:
python27Packages.buildPythonApplication {
pname = "resholve";
inherit version;
src = rSrc;
format = "other";
dontBuild = true;
nativeBuildInputs = [ installShellFiles ];
@ -32,13 +31,12 @@ python27Packages.buildPythonApplication {
];
patchPhase = ''
for file in resholve; do
for file in setup.cfg _resholve/version.py; do
substituteInPlace $file --subst-var-by version ${version}
done
'';
installPhase = ''
install -Dm755 resholve $out/bin/resholve
postInstall = ''
installManPage resholve.1
'';
@ -48,7 +46,10 @@ python27Packages.buildPythonApplication {
rm $out/nix-support/propagated-build-inputs
'';
passthru.tests = callPackage ./test.nix { inherit rSrc; inherit binlore; };
passthru = {
inherit (resholve-utils) mkDerivation phraseSolution writeScript writeScriptBin;
tests = callPackage ./test.nix { inherit rSrc binlore; };
};
meta = with lib; {
description = "Resolve external shell-script dependencies";

View file

@ -3,7 +3,7 @@
}:
rec {
version = "0.6.9";
version = "0.8.0";
rSrc =
# local build -> `make ci`; `make clean` to restore
# return to remote source
@ -14,6 +14,6 @@ rec {
owner = "abathur";
repo = "resholve";
rev = "v${version}";
hash = "sha256-y9O5w4wA/kR8zoPay9pGs3vwxNqq3JEeZmX0wBJq4UQ=";
hash = "sha256-oWS4ZBPjgH2UvYmvHVVRcyl15r3VS964BmB89y9DGo8=";
};
}

View file

@ -2,10 +2,8 @@
, stdenv
, callPackage
, resholve
, resholvePackage
, resholveScript
, resholveScriptBin
, shunit2
, fetchFromGitHub
, coreutils
, gnused
, gnugrep
@ -34,46 +32,7 @@ let
parsed_packages = [ coreutils sqlite util-linux gnused gawk findutils rlwrap gnutar bc ];
in
rec {
re_shunit2 = with shunit2;
resholvePackage {
inherit pname src version installPhase;
solutions = {
shunit = {
interpreter = "none";
scripts = [ "bin/shunit2" ];
inputs = [ coreutils gnused gnugrep findutils ];
# resholve's Nix API is analogous to the CLI flags
# documented in 'man resholve'
fake = {
# "missing" functions shunit2 expects the user to declare
function = [
"oneTimeSetUp"
"oneTimeTearDown"
"setUp"
"tearDown"
"suite"
"noexec"
];
# shunit2 is both bash and zsh compatible, and in
# some zsh-specific code it uses this non-bash builtin
builtin = [ "setopt" ];
};
fix = {
# stray absolute path; make it resolve from coreutils
"/usr/bin/od" = true;
};
keep = {
# variables invoked as commands; long-term goal is to
# resolve the *variable*, but that is complexish, so
# this is where we are...
"$__SHUNIT_CMD_ECHO_ESC" = true;
"$_SHUNIT_LINENO_" = true;
"$SHUNIT_CMD_TPUT" = true;
};
};
};
};
module1 = resholvePackage {
module1 = resholve.mkDerivation {
pname = "testmod1";
version = "unreleased";
@ -97,7 +56,7 @@ rec {
is_it_okay_with_arbitrary_envs = "shonuff";
};
module2 = resholvePackage {
module2 = resholve.mkDerivation {
pname = "testmod2";
version = "unreleased";
@ -105,19 +64,20 @@ rec {
setSourceRoot = "sourceRoot=$(echo */tests/nix/openssl)";
installPhase = ''
mkdir -p $out/bin
mkdir -p $out/bin $out/libexec
install openssl.sh $out/bin/openssl.sh
install libexec.sh $out/libexec/invokeme
install profile $out/profile
'';
# LOGLEVEL="DEBUG";
solutions = {
openssl = {
fix = {
aliases = true;
};
scripts = [ "bin/openssl.sh" ];
scripts = [ "bin/openssl.sh" "libexec/invokeme" ];
interpreter = "none";
inputs = [ re_shunit2 openssl.bin ];
inputs = [ shunit2 openssl.bin "libexec" "libexec/invokeme" ];
execer = [
/*
This is the same verdict binlore will
@ -136,7 +96,8 @@ rec {
};
};
};
module3 = resholvePackage {
# demonstrate that we could use resholve in larger build
module3 = stdenv.mkDerivation {
pname = "testmod3";
version = "unreleased";
@ -146,15 +107,15 @@ rec {
installPhase = ''
mkdir -p $out/bin
install conjure.sh $out/bin/conjure.sh
'';
solutions = {
conjure = {
${resholve.phraseSolution "conjure" {
scripts = [ "bin/conjure.sh" ];
interpreter = "${bash}/bin/bash";
inputs = [ module1 ];
};
};
fake = {
external = [ "jq" "openssl" ];
};
}}
'';
};
cli = stdenv.mkDerivation {
@ -204,14 +165,14 @@ rec {
};
# Caution: ci.nix asserts the equality of both of these w/ diff
resholvedScript = resholveScript "resholved-script" {
resholvedScript = resholve.writeScript "resholved-script" {
inputs = [ file ];
interpreter = "${bash}/bin/bash";
} ''
echo "Hello"
file .
'';
resholvedScriptBin = resholveScriptBin "resholved-script-bin" {
resholvedScriptBin = resholve.writeScriptBin "resholved-script-bin" {
inputs = [ file ];
interpreter = "${bash}/bin/bash";
} ''

View file

@ -1039,6 +1039,15 @@ mapAliases ({
redshift-wlr = throw "redshift-wlr has been replaced by gammastep"; # Added 2021-12-25
reicast = throw "reicast has been removed from nixpkgs as it is unmaintained, please use flycast instead"; # Added 2022-03-07
renpy = throw "renpy has been removed from nixpkgs, it was unmaintained and the latest packaged version required python2"; # Added 2022-01-12
/* 3 resholve aliases below added 2022-04-08 to ease breaking change
- convert to throw after 2022-07-01
- drop after 2022-11-30?
*/
resholvePackage = builtins.trace "resholvePackage is deprecated, use resholve.mkDerivation instead" resholve.mkDerivation;
resholveScript = builtins.trace "resholveScript is deprecated, use resholve.writeScript instead" resholve.writeScript;
resholveScriptBin = builtins.trace "resholveScriptBin is deprecated, use resholve.writeScriptBin instead" resholve.writeScriptBin;
residualvm = throw "residualvm was merged to scummvm code in 2018-06-15; consider using scummvm"; # Added 2021-11-27
retroArchCores = throw "retroArchCores has been removed. Please use overrides instead, e.g.: `retroarch.override { cores = with libretro; [ ... ]; }`"; # Added 2021-11-19
retroshare06 = retroshare;

View file

@ -9540,7 +9540,7 @@ with pkgs;
rescuetime = libsForQt5.callPackage ../applications/misc/rescuetime { };
inherit (callPackage ../development/misc/resholve { })
resholve resholvePackage resholveScript resholveScriptBin;
resholve;
restool = callPackage ../os-specific/linux/restool {};