Add repl subcommand

Fixes #115.
This commit is contained in:
Zhaofeng Li 2022-08-16 20:15:43 -06:00
parent 11add6501e
commit c540e00861
7 changed files with 63 additions and 0 deletions

View file

@ -14,6 +14,7 @@ let
"eval"
"exec"
"nix-info"
"repl"
];
renderHelp = subcommand: let
fullCommand = if subcommand == null then "colmena" else "colmena ${subcommand}";

View file

@ -30,3 +30,18 @@ You may directly instantiate an expression that evaluates to a derivation:
$ colmena eval --instantiate -E '{ nodes, ... }: nodes.alpha.config.boot.kernelPackages.kernel'
/nix/store/7ggmhnwvywrqcd1z2sdpan8afz55sw7z-linux-5.14.14.drv
```
## Interactive REPL
To explore the configurations interactively, start a REPL session with `colmena repl`:
```console
$ colmena repl
[INFO ] Using flake: git+file:///home/user/cluster
Welcome to Nix 2.10.3. Type :? for help.
Loading installable ''...
Added 3 variables.
nix-repl> nodes.alpha.config.deployment.targetHost
"fd12:3456::1"
```

View file

@ -11,6 +11,7 @@
- The [`meta.allowApplyAll`](./reference/meta.md#allowapplyall) option has been added. If set to false, deployments without a node filter (`--on`) are disallowed ([#95](https://github.com/zhaofengli/colmena/issues/95)).
- The `--no-substitutes` option under the `apply` subcommand has been renamed to `--no-substitute` ([#59](https://github.com/zhaofengli/colmena/issues/59)).
- The [`meta.nodeSpecialArgs`](./reference/meta.md#nodespecialargs) option has been added. It allows specifying node-specific `specialArgs` passed to NixOS modules ([#100](https://github.com/zhaofengli/colmena/pull/100)).
- The [`repl`](./reference/cli.html#colmena-repl) subcommand has been added. It allows you to start an [interactive REPL](./features/eval.md#interactive-repl) with access to the complete node configurations.
## [Release 0.3.0](https://github.com/zhaofengli/colmena/releases/tag/v0.3.0) (2022/04/27)

View file

@ -171,6 +171,7 @@ It's also possible to specify the preference using environment variables. See <h
register_command!(eval, app);
register_command!(upload_keys, app);
register_command!(exec, app);
register_command!(repl, app);
register_command!(nix_info, app);
// This does _not_ take the --color flag into account (haven't
@ -196,6 +197,7 @@ pub async fn run() {
handle_command!(eval, matches);
handle_command!("upload-keys", upload_keys, matches);
handle_command!(exec, matches);
handle_command!(repl, matches);
handle_command!("nix-info", nix_info, matches);
#[cfg(debug_assertions)]

View file

@ -3,6 +3,7 @@ pub mod build;
pub mod eval;
pub mod exec;
pub mod nix_info;
pub mod repl;
pub mod upload_keys;
#[cfg(target_os = "linux")]

38
src/command/repl.rs Normal file
View file

@ -0,0 +1,38 @@
use clap::{ArgMatches, Command as ClapCommand};
use tokio::process::Command;
use crate::error::ColmenaError;
use crate::util;
pub fn subcommand() -> ClapCommand<'static> {
ClapCommand::new("repl")
.about("Start an interactive REPL with the complete configuration")
.long_about(
r#"Start an interactive REPL with the complete configuration
In the REPL, you can inspect the configuration interactively with tab
completion. The node configurations are accessible under the `nodes`
attribute set."#,
)
}
pub async fn run(_global_args: &ArgMatches, local_args: &ArgMatches) -> Result<(), ColmenaError> {
let hive = util::hive_from_args(local_args).await?;
let expr = hive.get_repl_expression();
let status = Command::new("nix")
.arg("repl")
// `nix repl` is expected to be marked as experimental:
// <https://github.com/NixOS/nix/issues/5604>
.args(&["--experimental-features", "nix-command flakes"])
.args(&["--expr", &expr])
.status()
.await?;
if !status.success() {
return Err(status.into());
}
Ok(())
}

View file

@ -369,6 +369,11 @@ impl Hive {
}
}
/// Returns the expression for a REPL session.
pub fn get_repl_expression(&self) -> String {
format!("{} hive.introspect (x: x)", self.get_base_expression())
}
/// Returns the base expression from which the evaluated Hive can be used.
fn get_base_expression(&self) -> String {
self.assets.get_base_expression()