use std::process::Command;
use anyhow::{bail, Context, Result};
use console::style;
use crate::exec;
use crate::ops::develop;
const OMEGON_FLAKE: &str = "github:styrene-lab/omegon";
pub fn run(project: &str) -> Result<()> {
let flake_ref = develop::expand_flake_ref(project);
let nix = exec::find_nix();
println!(
" {} {} {}",
style("nex dev").bold(),
style(&flake_ref).cyan(),
style("+ omegon").dim()
);
let omegon_path = resolve_omegon(&nix)?;
let omegon_bin = format!("{omegon_path}/bin/omegon");
println!(" {} omegon resolved", style("✓").green().bold(),);
let auth_ok = Command::new(&omegon_bin)
.args(["auth", "status"])
.output()
.map(|o| {
let stdout = String::from_utf8_lossy(&o.stdout);
stdout.contains("authenticated") && !stdout.contains("Authenticated: 0")
})
.unwrap_or(false);
if !auth_ok {
println!(
" {} omegon not authenticated — launching login",
style("!").yellow()
);
let login = Command::new(&omegon_bin)
.args(["auth", "login"])
.status()
.context("failed to run omegon auth login")?;
if !login.success() {
bail!("omegon auth login failed — run `omegon auth login` manually");
}
} else {
println!(" {} omegon authenticated", style("✓").green().bold(),);
}
println!(
" {} entering dev shell + omegon interactive",
style(">>>").bold()
);
let status = Command::new(&nix)
.args([
"develop",
&flake_ref,
"-c",
"bash",
"-c",
&format!(
"export PATH=\"{omegon_path}/bin:$PATH\"; \
exec omegon interactive"
),
])
.status()
.context("failed to run nix develop")?;
if !status.success() {
bail!("dev session exited with {}", status.code().unwrap_or(-1));
}
Ok(())
}
fn resolve_omegon(nix: &str) -> Result<String> {
if let Ok(output) = Command::new("which").arg("omegon").output() {
if output.status.success() {
let path = String::from_utf8_lossy(&output.stdout).trim().to_string();
if !path.is_empty() {
if let Some(bin_dir) = std::path::Path::new(&path).parent() {
if let Some(pkg_dir) = bin_dir.parent() {
return Ok(pkg_dir.display().to_string());
}
}
return Ok(path);
}
}
}
println!(" {} resolving omegon...", style(">>>").bold());
let output = Command::new(nix)
.args(["build", OMEGON_FLAKE, "--no-link", "--print-out-paths"])
.output()
.context("failed to build omegon")?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
bail!(
"omegon is required for `nex dev` but could not be resolved.\n\
Install it: nix profile install {OMEGON_FLAKE}\n\
Error: {}",
stderr.lines().last().unwrap_or("unknown")
);
}
let path = String::from_utf8_lossy(&output.stdout).trim().to_string();
if path.is_empty() {
bail!(
"omegon is required for `nex dev` but build produced no output.\n\
Install it: nix profile install {OMEGON_FLAKE}"
);
}
Ok(path)
}