Read the output from the build process.

This commit is contained in:
Tom Alexander
2026-02-15 01:45:42 -05:00
parent e4670ac096
commit dd99900b90
4 changed files with 144 additions and 31 deletions

31
Cargo.lock generated
View File

@@ -498,9 +498,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.31" version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]] [[package]]
name = "futures-executor" name = "futures-executor"
@@ -526,15 +526,15 @@ dependencies = [
[[package]] [[package]]
name = "futures-io" name = "futures-io"
version = "0.3.31" version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.31" version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -543,21 +543,21 @@ dependencies = [
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.31" version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.31" version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
[[package]] [[package]]
name = "futures-util" name = "futures-util"
version = "0.3.31" version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-io", "futures-io",
@@ -566,7 +566,6 @@ dependencies = [
"futures-task", "futures-task",
"memchr", "memchr",
"pin-project-lite", "pin-project-lite",
"pin-utils",
"slab", "slab",
] ]
@@ -1295,12 +1294,6 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]] [[package]]
name = "pkcs1" name = "pkcs1"
version = "0.7.5" version = "0.7.5"

View File

@@ -38,9 +38,11 @@ pub(crate) async fn run_build(args: BuildArgs) -> Result<()> {
}; };
prepare_flake_repo(&config, target_config).await?; prepare_flake_repo(&config, target_config).await?;
build_target(&config, target_config).await?; build_target(&db_handle, &config, target_config).await?;
} }
db_handle.conn.close().await;
Ok(()) Ok(())
} }
@@ -74,7 +76,11 @@ async fn prepare_flake_repo(config_root: &Config, target_config: &TargetConfig)
Ok(()) Ok(())
} }
async fn build_target(config_root: &Config, target_config: &TargetConfig) -> Result<()> { async fn build_target(
db_handle: &DbHandle,
config_root: &Config,
target_config: &TargetConfig,
) -> Result<()> {
let flake_directory = target_config.get_flake_directory(config_root)?; let flake_directory = target_config.get_flake_directory(config_root)?;
let build_directory = target_config.get_build_directory(config_root)?; let build_directory = target_config.get_build_directory(config_root)?;
assert_directory!( assert_directory!(
@@ -83,7 +89,13 @@ async fn build_target(config_root: &Config, target_config: &TargetConfig) -> Res
build_directory.to_string_lossy() build_directory.to_string_lossy()
); );
nixos_build_target(build_directory, flake_directory, target_config.get_attr()?).await?; nixos_build_target(
db_handle,
build_directory,
flake_directory,
target_config.get_attr()?,
)
.await?;
Ok(()) Ok(())
} }

View File

@@ -9,6 +9,7 @@ use tracing::warn;
use super::migration::run_migrations; use super::migration::run_migrations;
use crate::Result; use crate::Result;
#[derive(Debug, Clone)]
pub(crate) struct DbHandle { pub(crate) struct DbHandle {
pub(crate) conn: Pool<Sqlite>, pub(crate) conn: Pool<Sqlite>,
} }

View File

@@ -1,16 +1,25 @@
use std::ffi::OsStr; use std::ffi::OsStr;
use std::ffi::OsString; use std::ffi::OsString;
use std::path::Path; use std::path::Path;
use std::process::Stdio;
use tokio::io::AsyncBufReadExt;
use tokio::io::BufReader;
use tokio::io::Lines;
use tokio::process::Child;
use tokio::process::ChildStderr;
use tokio::process::ChildStdout;
use tokio::process::Command; use tokio::process::Command;
use crate::error::CustomError; use crate::Result;
use crate::database::db_handle::DbHandle;
pub(crate) async fn nixos_build_target<B, F, A>( pub(crate) async fn nixos_build_target<B, F, A>(
db_handle: &DbHandle,
build_path: B, build_path: B,
flake_path: F, flake_path: F,
attr: A, attr: A,
) -> Result<(), CustomError> ) -> Result<()>
where where
B: AsRef<Path>, B: AsRef<Path>,
F: AsRef<Path>, F: AsRef<Path>,
@@ -29,6 +38,9 @@ where
// nixos-rebuild build --show-trace --sudo --max-jobs "$JOBS" --flake "$DIR/../../#odo" --log-format internal-json -v "${@}" // nixos-rebuild build --show-trace --sudo --max-jobs "$JOBS" --flake "$DIR/../../#odo" --log-format internal-json -v "${@}"
let mut command = Command::new("nixos-rebuild"); let mut command = Command::new("nixos-rebuild");
command.current_dir(build_path); command.current_dir(build_path);
command.stdout(Stdio::piped());
command.stderr(Stdio::piped());
command.stdin(Stdio::null());
command.args([ command.args([
"build", "build",
"--show-trace", "--show-trace",
@@ -38,21 +50,116 @@ where
"--log-format", "--log-format",
"internal-json", "internal-json",
"-v", "-v",
"--keep-going",
]); ]);
command.arg("--flake"); command.arg("--flake");
command.arg(reference); command.arg(reference);
command.kill_on_drop(true); command.kill_on_drop(true);
let mut child = command.spawn()?; let mut child = command.spawn()?;
let status = child.wait().await?;
if !status.success() { let mut output_stream = OutputSream::from_child(&mut child)?;
return Err("Nixos rebuild failed.".into());
let exit_status_handle = tokio::spawn(async move {
let status = child
.wait()
.await
.expect("nixos-rebuild encountered an error");
status
});
loop {
let next_line = output_stream.next_line().await?;
match next_line {
OutputLine::Stdout(line) => {
println!("STDOUT: {line}");
}
OutputLine::Stderr(line) => {
println!("STDERR: {line}");
}
OutputLine::Done => break,
};
} }
// tokio::spawn(async move { let exit_status = exit_status_handle.await?;
// let status = child.wait().await.expect("mpv encountered an error"); println!("nixos-rebuild status was: {}", exit_status);
// println!("mpv status was: {}", status);
// });
Ok(()) Ok(())
} }
struct OutputSream {
stdout: Option<Lines<BufReader<ChildStdout>>>,
stderr: Option<Lines<BufReader<ChildStderr>>>,
}
impl OutputSream {
pub(crate) fn from_child(child: &mut Child) -> Result<Self> {
let stdout = child
.stdout
.take()
.expect("child did not have a handle to stdout");
let stderr = child
.stderr
.take()
.expect("child did not have a handle to stderr");
let stdout = BufReader::new(stdout).lines();
let stderr = BufReader::new(stderr).lines();
Ok(OutputSream {
stdout: Some(stdout),
stderr: Some(stderr),
})
}
pub(crate) async fn next_line(&mut self) -> Result<OutputLine> {
loop {
match (&mut self.stdout, &mut self.stderr) {
(None, None) => {
return Ok(OutputLine::Done);
}
(None, Some(err)) => {
if let Some(line) = err.next_line().await? {
return Ok(OutputLine::Stderr(line));
} else {
return Ok(OutputLine::Done);
}
}
(Some(out), None) => {
if let Some(line) = out.next_line().await? {
return Ok(OutputLine::Stdout(line));
} else {
return Ok(OutputLine::Done);
}
}
(Some(out), Some(err)) => {
tokio::select! {
Ok(line) = out.next_line() => match line {
Some(line) => {
return Ok(OutputLine::Stdout(line));
},
None => {
self.stdout.take();
},
},
Ok(line) = err.next_line() => match line {
Some(line) => {
return Ok(OutputLine::Stderr(line));
},
None => {
self.stderr.take();
},
},
else => {
return Ok(OutputLine::Done);
},
};
}
};
}
}
}
enum OutputLine {
Stdout(String),
Stderr(String),
Done,
}