From dcc7f4b48f3c3d2d80ae810b4f716b62455599e7 Mon Sep 17 00:00:00 2001 From: Ryan Yin Date: Sun, 16 Jul 2023 13:00:39 +0800 Subject: [PATCH] feat: udpate for 'nix run' & 'nix shell' --- docs/development/intro.md | 71 +++++++-------- docs/other-usage-of-flakes/inputs.md | 36 ++++---- docs/other-usage-of-flakes/the-new-cli.md | 92 ++++++++++++++------ docs/zh/development/intro.md | 70 ++++++++------- docs/zh/other-usage-of-flakes/inputs.md | 16 ++-- docs/zh/other-usage-of-flakes/intro.md | 3 - docs/zh/other-usage-of-flakes/the-new-cli.md | 75 ++++++++++++---- 7 files changed, 230 insertions(+), 133 deletions(-) diff --git a/docs/development/intro.md b/docs/development/intro.md index 8cd8e5b..b192c40 100644 --- a/docs/development/intro.md +++ b/docs/development/intro.md @@ -242,49 +242,52 @@ Hello, world! This usage is mainly used to debug the build process of a Nix package, or to execute some commands in the build environment of a Nix package. -## `nix shell` & `nix run` +## `nix build` -Compare to `nix develop`, these two commands are much simpler and easier to understand. +The `nix build` command is used to build a software package and creates a symbolic link named `result` in the current directory, which points to the build result. -`nix shell` is used to enter an environment containing the specified Nix package and open an interactive shell for it: +Here's an example: -```shell -# hello not exists -› hello -hello: command not found - -# enter an environment containing hello -› nix shell nixpkgs#hello - -# now hello exists -› hello -Hello, world! +```bash +# Build the package 'ponysay' from the 'nixpkgs' flake +nix build "nixpkgs#ponysay" +# Use the built 'ponysay' command +› ./result/bin/ponysay 'hey buddy!' + ____________ +< hey buddy! > + ------------ + \ + \ + \ + ▄▄ ▄▄ ▄ ▄ + ▀▄▄▄█▄▄▄▄▄█▄▄▄ + ▀▄███▄▄██▄██▄▄██ + ▄██▄███▄▄██▄▄▄█▄██ + █▄█▄██▄█████████▄██ + ▄▄█▄█▄▄▄▄▄████████ + ▀▀▀▄█▄█▄█▄▄▄▄▄█████ ▄ ▄ + ▀▄████▄▄▄█▄█▄▄██ ▄▄▄▄▄█▄▄▄ + █▄██▄▄▄▄███▄▄▄██ ▄▄▄▄▄▄▄▄▄█▄▄ + ▀▄▄██████▄▄▄████ █████████████ + ▀▀▀▀▀█████▄▄ ▄▄▄▄▄▄▄▄▄▄██▄█▄▄▀ + ██▄███▄▄▄▄█▄▄▀ ███▄█▄▄▄█▀ + █▄██▄▄▄▄▄████ ███████▄██ + █▄███▄▄█████ ▀███▄█████▄ + ██████▀▄▄▄█▄█ █▄██▄▄█▄█▄ + ███████ ███████ ▀████▄████ + ▀▀█▄▄▄▀ ▀▀█▄▄▄▀ ▀██▄▄██▀█ + ▀ ▀▀█ ``` -`nix run` is used to create an environment containing the specified installable and run the installable in it(without install it to the system): +## Other Commands -```shell -# hello not exists -› hello -hello: command not found - -# enter an environment containing hello and run it -› nix run nixpkgs#hello -Hello, world! -``` - -Because `nix run` will directly run the Nix package as an installable, the Nix package used as its parameter must be able to generate an executable program. - -According to the description of `nix run --help`, `nix run` will execute `/bin/`, where `` is the root directory of a Derivation, and `` is selected in the following order: - -- The `meta.mainProgram` attribute of the derivation. -- The `pname` attribute of the derivation. -- The `name` part of the value of the name attribute of the derivation. - -For instance, if name is set to `hello-1.10`, nix run will run $out/bin/hello. +There are other commands like `nix flake init`, which you can explore in [New Nix Commands][New Nix Commands]. For more detailed information, please refer to the documentation. ## References - [pkgs.mkShell - nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell) - [A minimal nix-shell](https://fzakaria.com/2021/08/02/a-minimal-nix-shell.html) - [One too many shell, Clearing up with nix' shells nix shell and nix-shell - Yannik Sander](https://blog.ysndr.de/posts/guides/2021-12-01-nix-shells/) + +[New Nix Commands]: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix.html + diff --git a/docs/other-usage-of-flakes/inputs.md b/docs/other-usage-of-flakes/inputs.md index b23d4a0..83db04d 100644 --- a/docs/other-usage-of-flakes/inputs.md +++ b/docs/other-usage-of-flakes/inputs.md @@ -1,43 +1,49 @@ -# Flake inputs {#flake-inputs} +# Flake Inputs -The `inputs` in `flake.nix` is an attribute set, used to specify the dependencies of the current flake, there are many types of `inputs`, for example: +The `inputs` section in `flake.nix` is an attribute set used to specify the dependencies of the current flake. There are various types of inputs, as shown in the examples below: ```nix { inputs = { - # use master branch of the GitHub repository as input, this is the most common input format + # GitHub repository as the data source, specifying the master branch. This is the most common input format. nixpkgs.url = "github:Mic92/nixpkgs/master"; - # Git URL, can be used for any Git repository based on https/ssh protocol - git-example.url = "git+https://git.somehost.tld/user/path?ref=branch&rev=fdc8ef970de2b4634e1b3dca296e1ed918459a9e"; - # The above example will also copy .git, use this for (shallow) local Git repos + # Git URL, applicable to any Git repository using the https/ssh protocol. + git-example.url = "git+https://git.somehost.tld/user/path?ref=branch"; + # Similar to fetching a Git repository, but using the ssh protocol with key authentication. Also uses the shallow=1 parameter to avoid copying the .git directory. + ssh-git-example.url = "git+ssh://git@github.com/ryan4yin/nix-secrets.git?shallow=1"; + # It's also possible to directly depend on a local Git repository. git-directory-example.url = "git+file:/path/to/repo?shallow=1"; - # Local directories (for absolute paths you can omit 'path:') + # Using the `dir` parameter to specify a subdirectory. + nixpkgs.url = "github:foo/bar?dir=shu"; + # Local folder (if using an absolute path, the 'path:' prefix can be omitted). directory-example.url = "path:/path/to/repo"; + # If the data source is not a flake, set flake=false. + # `flake=false` is usually used to include additional source code, configuration files, etc. + # In Nix code, you can directly reference files within it using "${inputs.bar}/xxx/xxx" notation. + # For example, import "${inputs.bar}/xxx/xxx.nix" to import a specific nix file, + # or use "${inputs.bar}/xx/xx" as a path parameter for certain options. bar = { url = "github:foo/bar/branch"; - # if the input is not a flake, you need to set flake=false flake = false; }; sops-nix = { url = "github:Mic92/sops-nix"; - # The `follows` keyword in inputs is used for inheritance. - # Here, `inputs.nixpkgs` of sops-nix is kept consistent with the `inputs.nixpkgs` in - # the current flake, to avoid problems caused by different versions of nixpkgs. + # `follows` is the inheritance syntax within inputs. + # Here, it ensures that sops-nix's `inputs.nixpkgs` aligns with the current flake's inputs.nixpkgs, + # avoiding inconsistencies in the dependency's nixpkgs version. inputs.nixpkgs.follows = "nixpkgs"; }; - # Pin flakes to a specific revision + # Lock the flake to a specific commit. nix-doom-emacs = { url = "github:vlaci/nix-doom-emacs?rev=238b18d7b2c8239f676358634bfb32693d3706f3"; flake = false; }; - - # To use a subdirectory of a repo, pass `dir=xxx` - nixpkgs.url = "github:foo/bar?dir=shu"; }; outputs = { self, ... }@inputs: { ... }; } ``` + diff --git a/docs/other-usage-of-flakes/the-new-cli.md b/docs/other-usage-of-flakes/the-new-cli.md index 459d1e7..58b0a52 100644 --- a/docs/other-usage-of-flakes/the-new-cli.md +++ b/docs/other-usage-of-flakes/the-new-cli.md @@ -1,37 +1,77 @@ # Usage of the New CLI -Once you have enabled `nix-command` and `flake`, you can use the `nix help` command to obtain information about the [New Nix Commands][New Nix Commands]. Here are some useful examples: +Once you have enabled the `nix-command` and `flakes` features, you can start using the new generation Nix command-line tools provided by [New Nix Commands][New Nix Commands]. In this section, we will focus on two commands: `nix shell` and `nix run`. Other important commands like `nix build` will be discussed in detail in the chapter "Development Work on NixOS". -```bash -# The following command installs and runs the `ponysay` package from the `nixpkgs` flake. -# The `nixpkgs` flake refers to the `nixpkgs` repository on GitHub, which contains a `flake.nix` file. -# `nixpkgs` is a flake registry ID for `github:NixOS/nixpkgs/nixos-unstable`. -# You can find all the flake registry IDs at . -echo "Hello Nix" | nix run "nixpkgs#ponysay" +## `nix shell` -# this command is the same as above, but use a full flake URI instead of falkeregistry id. -echo "Hello Nix" | nix run "github:NixOS/nixpkgs/nixos-unstable#ponysay" +The `nix shell` command allows you to enter an environment with the specified Nix package and opens an interactive shell within that environment: -# instead of treat flake package as an application, -# this command use `devShells.example` in flake `zero-to-nix`'s outputs, to setup the development environment, -# and then open a bash shell in that environment. -nix develop "github:DeterminateSystems/zero-to-nix#example" +```shell +# hello is not available +› hello +hello: command not found -# instead of using a remote flake, you can open a bash shell using the flake located in the current directory. -mkdir my-flake && cd my-flake -# init a flake with template -nix flake init --template "github:DeterminateSystems/zero-to-nix#javascript-dev" -# open a bash shell using the flake in current directory -nix develop -# or if your flake has multiple devShell outputs, you can specify which one to use. -nix develop .#example +# Enter an environment with the 'hello' package +› nix shell nixpkgs#hello -# build package `bat` from flake `nixpkgs`, and put a symlink `result` in the current directory. -mkdir build-nix-package && cd build-nix-package -nix build "nixpkgs#bat" -# build a local flake is the same as nix develop, skip it +# hello is now available +› hello +Hello, world! ``` -We will introduce more details about `nix develop`, `nix shell` and `nix run` in the next chapter. +## `nix run` + +On the other hand, `nix run` creates an environment with the specified Nix package and directly runs that package within the environment (without installing it into the system environment): + +```shell +# hello is not available +› hello +hello: command not found + +# Create an environment with the 'hello' package and run it +› nix run nixpkgs#hello +Hello, world! +``` + +Since `nix run` directly executes the Nix package, the package specified as the argument must generate an executable program. + +According to the `nix run --help` documentation, `nix run` executes the command `/bin/`, where `` is the root directory of the derivation and `` is selected in the following order: + +- The `meta.mainProgram` attribute of the derivation +- The `pname` attribute of the derivation +- The content of the `name` attribute of the derivation with the version number removed + +For example, in the case of the 'hello' package we tested earlier, `nix run` actually executes the program `$out/bin/hello`. + +Here are two more examples with detailed explanations of the relevant parameters: + +```bash +# Explanation of the command: +# `nixpkgs#ponysay` means the 'ponysay' package in the 'nixpkgs' flake. +# `nixpkgs` is a flake registry id, and Nix will find the corresponding GitHub repository address +# from . +# Therefore, this command creates a new environment, installs, and runs the 'ponysay' package provided by the 'nixpkgs' flake. +# Note: It has been mentioned earlier that a Nix package is one of the outputs of a flake. +echo "Hello Nix" | nix run "nixpkgs#ponysay" + +# This command has the same effect as the previous one, but it uses the complete flake URI instead of the flake registry id. +echo "Hello Nix" | nix run "github:NixOS/nixpkgs/nixos-unstable#ponysay" +``` + +## Common Use Cases for `nix run` and `nix shell` + +These commands are commonly used for running temporary commands. For example, if I want to clone my configuration repository using Git on a new NixOS host without Git installed, I can use the following command: + +```bash +nix run nixpkgs#git clone git@github.com:ryan4yin/nix-config.git +``` + +Alternatively, you can use the following command: + +```bash +nix shell nixpkgs#git +git clone git@github.com:ryan4yin/nix-config.git +``` [New Nix Commands]: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix.html + diff --git a/docs/zh/development/intro.md b/docs/zh/development/intro.md index 76ea1ff..f3188c4 100644 --- a/docs/zh/development/intro.md +++ b/docs/zh/development/intro.md @@ -246,49 +246,53 @@ Hello, world! 这种用法的主要应用场景是调试某个 Nix 包的构建过程,或者在某个 Nix 包的构建环境中执行一些命令。 -## `nix shell` 与 `nix run` +## `nix build` -与 `nix develop` 相比,这两个命令就简单且好理解很多了。 +`nix build` 用于构建一个软件包,并在当前目录下创建一个名为 `result` 的符号链接,链接到该构建结果。 -`nix shell` 用于进入到一个含有指定 Nix 包的环境并为它打开一个交互式 shell: +一个示例: -```shell -# hello 不存在 -› hello -hello: command not found - -# 进入到一个含有 hello 的 shell 环境 -› nix shell nixpkgs#hello - -# hello 可以用了 -› hello -Hello, world! +```bash +# 构建 `nixpkgs` flake 中的 `ponysay` 这个包 +nix build "nixpkgs#ponysay" +# 使用构建出来的 ponysay 命令 +› ./result/bin/ponysay 'hey buddy!' + ____________ +< hey buddy! > + ------------ + \ + \ + \ + ▄▄ ▄▄ ▄ ▄ + ▀▄▄▄█▄▄▄▄▄█▄▄▄ + ▀▄███▄▄██▄██▄▄██ + ▄██▄███▄▄██▄▄▄█▄██ + █▄█▄██▄█████████▄██ + ▄▄█▄█▄▄▄▄▄████████ + ▀▀▀▄█▄█▄█▄▄▄▄▄█████ ▄ ▄ + ▀▄████▄▄▄█▄█▄▄██ ▄▄▄▄▄█▄▄▄ + █▄██▄▄▄▄███▄▄▄██ ▄▄▄▄▄▄▄▄▄█▄▄ + ▀▄▄██████▄▄▄████ █████████████ + ▀▀▀▀▀█████▄▄ ▄▄▄▄▄▄▄▄▄▄██▄█▄▄▀ + ██▄███▄▄▄▄█▄▄▀ ███▄█▄▄▄█▀ + █▄██▄▄▄▄▄████ ███████▄██ + █▄███▄▄█████ ▀███▄█████▄ + ██████▀▄▄▄█▄█ █▄██▄▄█▄█▄ + ███████ ███████ ▀████▄████ + ▀▀█▄▄▄▀ ▀▀█▄▄▄▀ ▀██▄▄██▀█ + ▀ ▀▀█ ``` -`nix run` 则是创建一个含有指定 Nix 包的环境,并在该环境中直接运行该 Nix 包(临时运行该程序,不将它安装到系统环境中): +## 其他命令 -```shell -# hello 不存在 -› hello -hello: command not found +其他还有些 `nix flake init` 之类的命令,请自行查阅 [New Nix Commands][New Nix Commands] 学习研究,这里就不详细介绍了。 -# 创建一个含有 hello 的环境并运行它 -› nix run nixpkgs#hello -Hello, world! -``` - -因为 `nix run` 会直接将 Nix 包运行起来,所以作为其参数的 Nix 包必须能生成一个可执行程序。 - -根据 `nix run --help` 的说明,`nix run` 会执行 `/bin/` 这个命令,其中 `` 是一个 Derivation 的根目录,`` 则按如下顺序进行选择尝试: - -- Derivation 的 `meta.mainProgram` 属性 -- Derivation 的 `pname` 属性 -- Derivation 的 `name` 属性中去掉版本号后的内容 - -比如说我们上面测试的包 hello,`nix run` 实际会执行 `$out/bin/hello` 这个程序。 ## References - [pkgs.mkShell - nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell) - [A minimal nix-shell](https://fzakaria.com/2021/08/02/a-minimal-nix-shell.html) - [One too many shell, Clearing up with nix' shells nix shell and nix-shell - Yannik Sander](https://blog.ysndr.de/posts/guides/2021-12-01-nix-shells/) + + +[New Nix Commands]: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix.html diff --git a/docs/zh/other-usage-of-flakes/inputs.md b/docs/zh/other-usage-of-flakes/inputs.md index eaa5f7c..362d4f6 100644 --- a/docs/zh/other-usage-of-flakes/inputs.md +++ b/docs/zh/other-usage-of-flakes/inputs.md @@ -8,12 +8,21 @@ # 以 GitHub 仓库为数据源,指定使用 master 分支,这是最常见的 input 格式 nixpkgs.url = "github:Mic92/nixpkgs/master"; # Git URL,可用于任何基于 https/ssh 协议的 Git 仓库 - git-example.url = "git+https://git.somehost.tld/user/path?ref=branch&rev=fdc8ef970de2b4634e1b3dca296e1ed918459a9e"; - # 上面的例子会复制 .git 到本地, 如果数据量较大,建议使用 shallow=1 参数避免复制 .git + git-example.url = "git+https://git.somehost.tld/user/path?ref=branch"; + # 同样是拉取 Git 仓库,但使用 ssh 协议 + 密钥认证,同时使用了 shallow=1 参数避免复制 .git + ssh-git-example.url = "git+ssh://git@github.com/ryan4yin/nix-secrets.git?shallow=1"; + # 当然也可以直接依赖本地的 git 仓库 git-directory-example.url = "git+file:/path/to/repo?shallow=1"; + # 使用 `dir` 参数指定某个子目录 + nixpkgs.url = "github:foo/bar?dir=shu"; # 本地文件夹 (如果使用绝对路径,可省略掉前缀 'path:') directory-example.url = "path:/path/to/repo"; + # 如果数据源不是一个 flake,则需要设置 flake=false + # `flake=false` 通常被用于引入一些额外的源代码、配置文件等 + # 在 nix 代码中可以直接通过 "${inputs.bar}/xxx/xxx" 的方式来引用其中的文件 + # 比如说通过 `import "${inputs.bar}/xxx/xxx.nix"` 来导入其中的 nix 文件 + # 或者直接将 "${inputs.bar}/xx/xx" 当作某些 option 的路径参数使用 bar = { url = "github:foo/bar/branch"; flake = false; @@ -32,9 +41,6 @@ url = "github:vlaci/nix-doom-emacs?rev=238b18d7b2c8239f676358634bfb32693d3706f3"; flake = false; }; - - # 使用 `dir` 参数指定某个子目录 - nixpkgs.url = "github:foo/bar?dir=shu"; }; outputs = { self, ... }@inputs: { ... }; diff --git a/docs/zh/other-usage-of-flakes/intro.md b/docs/zh/other-usage-of-flakes/intro.md index 85da6cf..a238ac3 100644 --- a/docs/zh/other-usage-of-flakes/intro.md +++ b/docs/zh/other-usage-of-flakes/intro.md @@ -2,6 +2,3 @@ 到这里我们已经写了不少 Nix Flakes 配置来管理 NixOS 系统了,这里再简单介绍下 Nix Flakes 更细节的内容,以及常用的 nix flake 命令。 -此外 [Zero to Nix - Determinate Systems][Zero to Nix - Determinate Systems] 是一份全新的 Nix & Flake 新手入门文档,写得比较浅显易懂,也可以一读。 - -[Zero to Nix - Determinate Systems]: https://github.com/DeterminateSystems/zero-to-nix diff --git a/docs/zh/other-usage-of-flakes/the-new-cli.md b/docs/zh/other-usage-of-flakes/the-new-cli.md index ce8c213..1aa6c36 100644 --- a/docs/zh/other-usage-of-flakes/the-new-cli.md +++ b/docs/zh/other-usage-of-flakes/the-new-cli.md @@ -1,6 +1,50 @@ # 新一代 Nix 命令行工具的使用 {#flake-commands-usage} -在启用了 `nix-command` & `flakes` 功能后,我们就可以使用 Nix 提供的新一代 Nix 命令行工具 [New Nix Commands][New Nix Commands] 了,下面列举下其中常用命令的用法: +在启用了 `nix-command` & `flakes` 功能后,我们就可以使用 Nix 提供的新一代 Nix 命令行工具 [New Nix Commands][New Nix Commands] 了, +这里主要介绍 `nix shell` 与 `nix run` 两个命令,其他重要的命令(如 `nix shell` `nix build`)将在「在 NixOS 上进行开发工作」一章中再详细介绍。 + +## `nix shell` + +`nix shell` 用于进入到一个含有指定 Nix 包的环境并为它打开一个交互式 shell: + +```shell +# hello 不存在 +› hello +hello: command not found + +# 进入到一个含有 hello 的 shell 环境 +› nix shell nixpkgs#hello + +# hello 可以用了 +› hello +Hello, world! +``` + +## `nix run` + +`nix run` 则是创建一个含有指定 Nix 包的环境,并在该环境中直接运行该 Nix 包(临时运行该程序,不将它安装到系统环境中): + +```shell +# hello 不存在 +› hello +hello: command not found + +# 创建一个含有 hello 的环境并运行它 +› nix run nixpkgs#hello +Hello, world! +``` + +因为 `nix run` 会直接将 Nix 包运行起来,所以作为其参数的 Nix 包必须能生成一个可执行程序。 + +根据 `nix run --help` 的说明,`nix run` 会执行 `/bin/` 这个命令,其中 `` 是一个 Derivation 的根目录,`` 则按如下顺序进行选择尝试: + +- Derivation 的 `meta.mainProgram` 属性 +- Derivation 的 `pname` 属性 +- Derivation 的 `name` 属性中去掉版本号后的内容 + +比如说我们上面测试的包 hello,`nix run` 实际会执行 `$out/bin/hello` 这个程序。 + +再给两个示例,并详细说明下相关参数: ```bash # 解释下这条指令涉及的参数: @@ -14,25 +58,22 @@ echo "Hello Nix" | nix run "nixpkgs#ponysay" # 这条命令和上面的命令作用是一样的,只是使用了完整的 flake URI,而不是 flakeregistry id。 echo "Hello Nix" | nix run "github:NixOS/nixpkgs/nixos-unstable#ponysay" +``` -# 这条命令的作用是使用 zero-to-nix 这个 flake 中名 `devShells.example` 的 outptus 来创建一个开发环境, -# 然后在这个环境中打开一个 bash shell。 -nix develop "github:DeterminateSystems/zero-to-nix#example" -# 除了使用远程 flake uri 之外,你也可以使用当前目录下的 flake 来创建一个开发环境。 -mkdir my-flake && cd my-flake -# 通过模板初始化一个 flake -nix flake init --template "github:DeterminateSystems/zero-to-nix#javascript-dev" -# 使用当前目录下的 flake 创建一个开发环境,并打开一个 bash shell -nix develop -# 或者如果你的 flake 有多个 devShell 输出,你可以指定使用名为 example 的那个 -nix develop .#example +## `nix run` 与 `nix shell` 的常见用途 -# 构建 `nixpkgs` flake 中的 `bat` 这个包 -# 并在当前目录下创建一个名为 `result` 的符号链接,链接到该构建结果文件夹。 -mkdir build-nix-package && cd build-nix-package -nix build "nixpkgs#bat" -# 构建一个本地 flake 和 nix develop 是一样的,不再赘述 +那显然就是用来跑些临时命令,比如说我在新 NixOS 主机上恢复环境,但是还没有装 Git,我可以直接用如下命令临时使用 Git 克隆我的配置仓库: + +```bash +nix run nixpkgs#git clone git@github.com:ryan4yin/nix-config.git +``` + +或者也可以这样: + +```bash +nix shell nixpkgs#git +git clone git@github.com:ryan4yin/nix-config.git ``` [New Nix Commands]: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix.html