基于属性向 stdenv 添加一个 shell 函数
Add a shell function to the stdenv based on attribute
有没有简单的方法可以在stdenv提供的环境中添加一个bash函数?当使用 'nix-shell' 进行开发时,我可以 运行 命令,例如 'unpackPhase' 或 'buildPhase',因为 mkDerivation
将它们放在范围内——它非常有用。我的派生属性也被添加到环境中。但我也希望看到一种在 build/shell 环境中自动添加属性作为函数的方法。
为了解释我的意思,我目前可以通过使用 eval
语句或 toFile
和 source
将函数添加到环境中。例如,对于 eval
,类似于:
{ stdenv, ... } : stdenv.mkDerivation
{ shellHook = ''eval "$myFunctions"'';
myFunctions = ''
myFunction1(){
echo "doing myFunction1"
}
myFunction2(){
echo "doing myFunction2"
}
''
}
当我输入nix-shell
时,会"source"myFunction1
和myFunction2
。
但是,我期待像 mkFunction
实用程序这样的东西来补充 mkWrapper
、mkProgram
和其他此类基本实用程序。我希望像下面那样使用它,其中使用 mkFunction
定义的属性会自动 "sourced" 如上所述。
{ stdenv, mkFunction, ... } : stdenv.mkDerivation
{ myFunction1 = mkFunction '' echo "doing myFunction1" '';
myFunction2 = mkFunction '' echo "doing myFunction2" '';
shellHook = '' echo "No need to source, myFunctions are already in scope." '';
}
我认为这样的实用程序会很有用。我认为 setup hooks 可能涵盖这种用途,但我不确定如何使用它们。以第一种方式做它并没有那么糟糕(如果我在写这个问题的过程中没有弄明白我就不会费心去问了)。但它似乎是 nix
已经可用的那种实用程序,所以我还是要问。
设置挂钩确实可以做到这一点,这是一个定义函数的简单示例 foo
:
with import <nixpkgs> {};
let
fooHook = stdenv.mkDerivation {
name = "foo-hook";
# Setting phases directly is usually discouraged, but in this case we really
# only need fixupPhase because that's what installs setup hooks
phases = [ "fixupPhase" ];
setupHook = writeText "my-setup-hook" ''
foo() { echo "Foo was called!"; }
'';
};
in mkShell {
buildInputs = [ fooHook ];
shellHook = "foo";
}
运行 nix-shell
在此产生所需的结果:
$ nix-shell
Foo was called!
[nix-shell:~]$
另一种简单的可能性是使用stdenv提供的runHook
函数。
with import <nixpkgs> {};
mkShell rec {
name = "runs-hook";
myFun = "echo The name is ${name}";
}
在上面的代码片段中,变量 myFun
在 shell/build 环境中可用。您可以这样称呼它:
> runHook myFun
The name is runs-hook
这与问题中的 eval
方法非常相似。
有没有简单的方法可以在stdenv提供的环境中添加一个bash函数?当使用 'nix-shell' 进行开发时,我可以 运行 命令,例如 'unpackPhase' 或 'buildPhase',因为 mkDerivation
将它们放在范围内——它非常有用。我的派生属性也被添加到环境中。但我也希望看到一种在 build/shell 环境中自动添加属性作为函数的方法。
为了解释我的意思,我目前可以通过使用 eval
语句或 toFile
和 source
将函数添加到环境中。例如,对于 eval
,类似于:
{ stdenv, ... } : stdenv.mkDerivation
{ shellHook = ''eval "$myFunctions"'';
myFunctions = ''
myFunction1(){
echo "doing myFunction1"
}
myFunction2(){
echo "doing myFunction2"
}
''
}
当我输入nix-shell
时,会"source"myFunction1
和myFunction2
。
但是,我期待像 mkFunction
实用程序这样的东西来补充 mkWrapper
、mkProgram
和其他此类基本实用程序。我希望像下面那样使用它,其中使用 mkFunction
定义的属性会自动 "sourced" 如上所述。
{ stdenv, mkFunction, ... } : stdenv.mkDerivation
{ myFunction1 = mkFunction '' echo "doing myFunction1" '';
myFunction2 = mkFunction '' echo "doing myFunction2" '';
shellHook = '' echo "No need to source, myFunctions are already in scope." '';
}
我认为这样的实用程序会很有用。我认为 setup hooks 可能涵盖这种用途,但我不确定如何使用它们。以第一种方式做它并没有那么糟糕(如果我在写这个问题的过程中没有弄明白我就不会费心去问了)。但它似乎是 nix
已经可用的那种实用程序,所以我还是要问。
设置挂钩确实可以做到这一点,这是一个定义函数的简单示例 foo
:
with import <nixpkgs> {};
let
fooHook = stdenv.mkDerivation {
name = "foo-hook";
# Setting phases directly is usually discouraged, but in this case we really
# only need fixupPhase because that's what installs setup hooks
phases = [ "fixupPhase" ];
setupHook = writeText "my-setup-hook" ''
foo() { echo "Foo was called!"; }
'';
};
in mkShell {
buildInputs = [ fooHook ];
shellHook = "foo";
}
运行 nix-shell
在此产生所需的结果:
$ nix-shell
Foo was called!
[nix-shell:~]$
另一种简单的可能性是使用stdenv提供的runHook
函数。
with import <nixpkgs> {};
mkShell rec {
name = "runs-hook";
myFun = "echo The name is ${name}";
}
在上面的代码片段中,变量 myFun
在 shell/build 环境中可用。您可以这样称呼它:
> runHook myFun
The name is runs-hook
这与问题中的 eval
方法非常相似。