Skip to content

Commit

Permalink
devenv.isTesting
Browse files Browse the repository at this point in the history
  • Loading branch information
domenkozar committed May 9, 2024
1 parent 4d786c3 commit f937088
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 63 deletions.
1 change: 1 addition & 0 deletions devenv/src/flake.tmpl.nix
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
(pkgs.lib.optionalAttrs (inputs.devenv.isTmpDir or false) {
devenv.tmpdir = devenv_tmpdir;
devenv.runtime = devenv_runtime;
devenv.isTesting = devenv_istesting;
})
(pkgs.lib.optionalAttrs (container_name != null) {
container.isBuilding = pkgs.lib.mkForce true;
Expand Down
133 changes: 70 additions & 63 deletions devenv/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ struct App {
logger: log::Logger,
has_processes: Option<bool>,
container_name: Option<String>,
assembled: bool,
// all kinds of paths
devenv_root: PathBuf,
devenv_dotfile: PathBuf,
Expand Down Expand Up @@ -300,6 +301,7 @@ fn main() -> Result<()> {
let mut app = App {
cli,
config,
assembled: false,
has_processes: None,
logger,
container_name: None,
Expand Down Expand Up @@ -387,7 +389,7 @@ fn main() -> Result<()> {
InputsCommand::Add { name, url, follows } => app.inputs_add(&name, &url, &follows),
},
// hidden
Commands::Assemble => app.assemble(),
Commands::Assemble => app.assemble(false),
Commands::PrintDevEnv { json } => app.print_dev_env(json),
Commands::GenerateJSONSchema => {
config::write_json_schema();
Expand Down Expand Up @@ -491,7 +493,7 @@ impl App {
}

fn prepare_shell(&mut self, cmd: &Option<String>, args: &[String]) -> Result<Vec<String>> {
self.assemble()?;
self.assemble(false)?;
let (_, gc_root) = self.get_dev_environment(false, true)?;

let mut develop_args = vec![
Expand Down Expand Up @@ -544,7 +546,7 @@ impl App {
None => "Updating devenv.lock".to_string(),
};
let _logprogress = log::LogProgress::new(&msg, true);
self.assemble()?;
self.assemble(false)?;

match input_name {
Some(input_name) => {
Expand All @@ -568,7 +570,7 @@ impl App {

let _logprogress = log::LogProgress::new(&format!("Building {name} container"), true);

self.assemble()?;
self.assemble(false)?;

let container_store_path = self.run_nix(
"nix",
Expand Down Expand Up @@ -730,7 +732,7 @@ impl App {
}

fn search(&mut self, name: &str) -> Result<()> {
self.assemble()?;
self.assemble(false)?;

let options = self.run_nix(
"nix",
Expand Down Expand Up @@ -820,7 +822,7 @@ impl App {
// TODO: don't add gc roots for tests
self.devenv_dot_gc = self.devenv_dotfile.join("gc");
}
self.assemble()?;
self.assemble(true)?;

// collect tests
let test_script = {
Expand Down Expand Up @@ -877,7 +879,7 @@ impl App {
}

fn info(&mut self) -> Result<()> {
self.assemble()?;
self.assemble(false)?;

// TODO: use --json
let metadata = self.run_nix("nix", &["flake", "metadata"], &command::Options::default())?;
Expand All @@ -899,7 +901,7 @@ impl App {
}

fn build(&mut self, attributes: &[String]) -> Result<()> {
self.assemble()?;
self.assemble(false)?;

let formatted_strings: Vec<String> = attributes
.iter()
Expand Down Expand Up @@ -932,7 +934,7 @@ impl App {
}

fn up(&mut self, process: Option<&str>, detach: &bool, log_to_file: &bool) -> Result<()> {
self.assemble()?;
self.assemble(false)?;
if !self.has_processes()? {
self.logger
.error("No 'processes' option defined: https://devenv.sh/processes/");
Expand Down Expand Up @@ -1051,67 +1053,72 @@ impl App {
Ok(())
}

fn assemble(&mut self) -> Result<()> {
if !PathBuf::from("devenv.nix").exists() {
bail!(indoc::indoc! {"
File devenv.nix does not exist. To get started, run:
fn assemble(&mut self, is_testing: bool) -> Result<()> {
if !self.assembled {
if !PathBuf::from("devenv.nix").exists() {
bail!(indoc::indoc! {"
File devenv.nix does not exist. To get started, run:
$ devenv init
"});
}
std::fs::create_dir_all(&self.devenv_dot_gc)
.unwrap_or_else(|_| panic!("Failed to create {}", self.devenv_dot_gc.display()));
$ devenv init
"});
}
std::fs::create_dir_all(&self.devenv_dot_gc)
.unwrap_or_else(|_| panic!("Failed to create {}", self.devenv_dot_gc.display()));

let mut flake_inputs = HashMap::new();
for (input, attrs) in self.config.inputs.iter() {
flake_inputs.insert(input.clone(), config::FlakeInput::from(attrs));
let mut flake_inputs = HashMap::new();
for (input, attrs) in self.config.inputs.iter() {
flake_inputs.insert(input.clone(), config::FlakeInput::from(attrs));
}
fs::write(
self.devenv_dotfile.join("flake.json"),
serde_json::to_string(&flake_inputs).unwrap(),
)
.expect("Failed to write flake.json");
fs::write(
self.devenv_dotfile.join("devenv.json"),
serde_json::to_string(&self.config).unwrap(),
)
.expect("Failed to write devenv.json");
fs::write(
self.devenv_dotfile.join("imports.txt"),
self.config.imports.join("\n"),
)
.expect("Failed to write imports.txt");

// create flake.devenv.nix
let vars = indoc::formatdoc!(
"version = \"{}\";
system = \"{}\";
devenv_root = \"{}\";
devenv_dotfile = ./{};
devenv_dotfile_string = \"{}\";
container_name = {};
devenv_tmpdir = \"{}\";
devenv_runtime = \"{}\";
devenv_istesting = {};
",
crate_version!(),
self.cli.system,
self.devenv_root.display(),
self.devenv_dotfile.file_name().unwrap().to_str().unwrap(),
self.devenv_dotfile.file_name().unwrap().to_str().unwrap(),
self.container_name
.as_deref()
.map(|s| format!("\"{}\"", s))
.unwrap_or_else(|| "null".to_string()),
self.devenv_tmp,
self.devenv_runtime.display(),
is_testing
);
let flake = FLAKE_TMPL.replace("__DEVENV_VARS__", &vars);
std::fs::write(DEVENV_FLAKE, flake).expect("Failed to write flake.nix");
}
fs::write(
self.devenv_dotfile.join("flake.json"),
serde_json::to_string(&flake_inputs).unwrap(),
)
.expect("Failed to write flake.json");
fs::write(
self.devenv_dotfile.join("devenv.json"),
serde_json::to_string(&self.config).unwrap(),
)
.expect("Failed to write devenv.json");
fs::write(
self.devenv_dotfile.join("imports.txt"),
self.config.imports.join("\n"),
)
.expect("Failed to write imports.txt");

// create flake.devenv.nix
let vars = indoc::formatdoc!(
"version = \"{}\";
system = \"{}\";
devenv_root = \"{}\";
devenv_dotfile = ./{};
devenv_dotfile_string = \"{}\";
container_name = {};
devenv_tmpdir = \"{}\";
devenv_runtime = \"{}\";
",
crate_version!(),
self.cli.system,
self.devenv_root.display(),
self.devenv_dotfile.file_name().unwrap().to_str().unwrap(),
self.devenv_dotfile.file_name().unwrap().to_str().unwrap(),
self.container_name
.as_deref()
.map(|s| format!("\"{}\"", s))
.unwrap_or_else(|| "null".to_string()),
self.devenv_tmp,
self.devenv_runtime.display(),
);
let flake = FLAKE_TMPL.replace("__DEVENV_VARS__", &vars);
std::fs::write(DEVENV_FLAKE, flake).expect("Failed to write flake.nix");
self.assembled = true;
Ok(())
}

fn get_dev_environment(&mut self, json: bool, logging: bool) -> Result<(Vec<u8>, PathBuf)> {
self.assemble()?;
self.assemble(false)?;
let _logprogress = if logging {
Some(log::LogProgress::new("Building shell", true))
} else {
Expand Down
8 changes: 8 additions & 0 deletions docs/tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ ncdu 2.2
✔ Tests passed. in 0.0s.
```

## Changing environment only for tests

```nix title="devenv.nix"
{ pkgs, config, ... }: {
services.postgres.enable = config.devenv.isTesting;
}
```

## Provided functions for enterTest

- `wait_for_port <port> <timeout>`: waits for a port to be open
Expand Down
5 changes: 5 additions & 0 deletions src/modules/tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
description = "Bash code to execute to run the test.";
};

devenv.isTesting = lib.mkOption {
type = lib.types.bool;
default = false;
};

test = lib.mkOption {
type = lib.types.package;
internal = true;
Expand Down

0 comments on commit f937088

Please sign in to comment.