diff --git a/Cargo.lock b/Cargo.lock index 29498a9e7..b1f35352d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1906,5 +1906,6 @@ name = "xtask" version = "0.1.0" dependencies = [ "clap", + "color-eyre", "tonic-build", ] diff --git a/console-api/tests/bootstrap.rs b/console-api/tests/bootstrap.rs index ed48c6a13..1884ebbfd 100644 --- a/console-api/tests/bootstrap.rs +++ b/console-api/tests/bootstrap.rs @@ -1,38 +1,49 @@ -use std::{path::PathBuf, process::Command}; +use std::{fs, path::PathBuf, process::Command}; #[test] fn bootstrap() { - let iface_files = &[ - "proto/trace.proto", - "proto/common.proto", - "proto/tasks.proto", - "proto/instrument.proto", - "proto/resources.proto", - "proto/async_ops.proto", - ]; - let dirs = &["proto"]; + let root_dir = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")); + let proto_dir = root_dir.join("proto"); + let proto_files = fs::read_dir(&proto_dir).and_then(|dir| { + dir.filter_map(|entry| { + (|| { + let entry = entry?; + if entry.file_type()?.is_dir() { + return Ok(None); + } + Ok(Some(entry.path())) + })() + .transpose() + }) + .collect::, _>>() + }); + let proto_files = match proto_files { + Ok(files) => files, + Err(error) => panic!("failed to list proto files: {}", error), + }; - let out_dir = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")) - .join("src") - .join("generated"); + let out_dir = root_dir.join("src").join("generated"); - tonic_build::configure() + if let Err(error) = tonic_build::configure() .build_client(true) .build_server(true) + .emit_rerun_if_changed(false) .protoc_arg("--experimental_allow_proto3_optional") - .out_dir(format!("{}", out_dir.display())) - .compile(iface_files, dirs) - .unwrap(); + .out_dir(&out_dir) + .compile(&proto_files[..], &[proto_dir]) + { + panic!("failed to compile `console-api` protobuf: {}", error); + } let status = Command::new("git") .arg("diff") .arg("--exit-code") .arg("--") - .arg(format!("{}", out_dir.display())) - .status() - .unwrap(); - - if !status.success() { - panic!("You should commit the protobuf files"); + .arg(out_dir) + .status(); + match status { + Ok(status) if !status.success() => panic!("You should commit the protobuf files"), + Err(error) => panic!("failed to run `git diff`: {}", error), + Ok(_) => {} } } diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index c0bfadebc..09f60941a 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -10,4 +10,5 @@ publish = false tonic-build = { version = "0.8", default-features = false, features = [ "prost", "transport" ] } -clap = { version = "3", features = ["derive"] } \ No newline at end of file +clap = { version = "3", features = ["derive"] } +color-eyre = "0.5" \ No newline at end of file diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 4bd19267f..1bbdf045b 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,5 +1,6 @@ use clap::Parser; -use std::path::PathBuf; +use std::{fs, path::PathBuf}; +use color_eyre::{Result, eyre::{ensure, WrapErr}}; /// tokio-console dev tasks #[derive(Debug, clap::Parser)] @@ -14,50 +15,50 @@ enum Command { GenProto, } -fn main() { - let args = Args::parse(); - if let Err(error) = args.cmd.run() { - eprintln!("{error}"); - std::process::exit(1) - } +fn main() -> Result<()> { + color_eyre::install()?; + Args::parse().cmd.run() } impl Command { - fn run(&self) -> Result<(), Box> { + fn run(&self) -> Result<()> { match self { Self::GenProto => gen_proto(), } } } -fn gen_proto() -> Result<(), Box> { +fn gen_proto() -> Result<()> { eprintln!("generating `console-api` protos..."); let api_dir = { let mut mydir = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")); - assert!(mydir.pop(), "manifest path should not be relative!"); + ensure!(mydir.pop(), "manifest path should not be relative!"); mydir.join("console-api") }; let proto_dir = api_dir.join("proto"); - let out_dir = api_dir.join("src").join("generated"); + let proto_files = fs::read_dir(&proto_dir).with_context(|| format!("failed to read protobuf directory `{}`", proto_dir.display()))? + .filter_map(|entry| { + (|| { + let entry = entry?; + if entry.file_type()?.is_dir() { + return Ok(None); + } + Ok(Some(entry.path())) + })() + .transpose() + }) + .collect::>>()?; - let iface_files = &[ - proto_dir.join("trace.proto"), - proto_dir.join("common.proto"), - proto_dir.join("tasks.proto"), - proto_dir.join("instrument.proto"), - proto_dir.join("resources.proto"), - proto_dir.join("async_ops.proto"), - ]; + let out_dir = api_dir.join("src").join("generated"); tonic_build::configure() .build_client(true) - .build_server(true) + .build_server(true)git + .emit_rerun_if_changed(false) .protoc_arg("--experimental_allow_proto3_optional") - .out_dir(format!("{}", out_dir.display())) - .compile(iface_files, &[proto_dir])?; - - eprintln!("protos regenerated!"); - Ok(()) + .out_dir(&out_dir) + .compile(&proto_files[..], &[proto_dir]) + .context("failed to compile protobuf files") }