blob: 2b6840e45301ef1b704e9aef60588f72a9e58f79 [file] [log] [blame]
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::ffi::OsStr;
use xshell::cmd;
#[derive(clap::Subcommand, Debug, Clone)]
pub enum CargoWorkspaceSubcommand {
/// Checks test, clippy, and cargo deny in the workspace
CheckWorkspace(CargoOptions),
/// Checks the formatting of the workspace
CheckFormat(FormatterOptions),
}
impl CargoWorkspaceSubcommand {
pub fn run(&self, tag: &str, sh: &xshell::Shell) -> anyhow::Result<()> {
match self {
CargoWorkspaceSubcommand::CheckWorkspace(cargo_options) => {
cargo_options.check_workspace(sh, tag)
}
CargoWorkspaceSubcommand::CheckFormat(formatter_options) => {
formatter_options.check_format(sh)
}
}
}
}
#[derive(clap::Args, Debug, Clone, Default)]
pub struct CargoOptions {
#[arg(long, help = "whether to run cargo with --locked")]
locked: bool,
#[arg(long, help = "gather coverage metrics")]
coverage: bool,
}
impl CargoOptions {
/// Run `cargo test` or `cargo llvm-cov` depending on the configured options.
pub fn test<'sh, S: AsRef<OsStr>>(
&self,
sh: &'sh xshell::Shell,
tag: &str,
args: impl IntoIterator<Item = S>,
) -> xshell::Cmd<'sh> {
let locked = if self.locked { "--locked" } else { "" };
if self.coverage {
cmd!(
sh,
"cargo llvm-cov {locked} {args...} --lcov --output-path target/{tag}.info -- --color=always"
)
} else {
cmd!(sh, "cargo test {locked} {args...} -- --color=always")
}
}
/// Run the default set of checks on a cargo workspace
pub fn check_workspace(&self, sh: &xshell::Shell, tag: &str) -> anyhow::Result<()> {
self.test(sh, tag, ["--workspace"]).run()?;
cmd!(
sh,
"cargo clippy --all-targets --workspace -- --deny warnings"
)
.run()?;
cmd!(sh, "cargo deny --workspace check").run()?;
// ensure the docs are valid (cross-references to other code, etc)
cmd!(
sh,
"cargo doc --quiet --workspace --no-deps --document-private-items
--target-dir target/dist_docs/{tag}"
)
.env("RUSTDOCFLAGS", "--deny warnings")
.run()?;
Ok(())
}
}
#[derive(clap::Args, Debug, Clone, Default)]
pub struct FormatterOptions {
#[arg(
long,
help = "reformat files files in the workspace with the code formatter"
)]
pub reformat: bool,
}
impl FormatterOptions {
pub fn check_format(&self, sh: &xshell::Shell) -> anyhow::Result<()> {
if self.reformat {
cmd!(sh, "cargo fmt").run()?;
} else {
cmd!(sh, "cargo fmt --check").run()?;
}
Ok(())
}
}