Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,15 @@ members = [
"crates/x509",
"ddi/interface",
"ddi/lib",
"ddi/mock",
"ddi/nix",
"ddi/res_test_dev",
"ddi/serde/derive",
"ddi/serde/mbor",
"ddi/serde/types",
"ddi/sim",
"ddi/test_helpers",
"ddi/win",
Comment thread
zimmy87 marked this conversation as resolved.
"plugins/ossl_prov",
"plugins/ossl_prov/integration-tests/nginx",
"plugins/ossl_prov/integration-tests/openssl-capi",
Expand Down Expand Up @@ -104,6 +111,7 @@ spki = "0.7.3"
syn = "2"
test-log = "0.2.8"
thiserror = "1.0"
toml_edit = "0.25.11"
tracing = "0.1"
tracing-subscriber = "0.3.16"
tracing-tree = "0.4.1"
Expand Down
1 change: 1 addition & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ junit-parser.workspace = true
jzon.workspace = true
log.workspace = true
similar = { features = ["text"], workspace = true }
toml_edit.workspace = true
xshell.workspace = true

[lints]
Expand Down
3 changes: 3 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ mod openssl_install;
mod precheck;
mod rustup_component_add;
mod setup;
mod validate_members;

/// Common context passed into every Xtask
#[derive(Clone)]
Expand Down Expand Up @@ -77,6 +78,7 @@ enum Commands {
Setup(setup::Setup),
Install(install::Install),
RustupComponentAdd(rustup_component_add::RustupComponentAdd),
ValidateMembers(validate_members::ValidateMembers),
}

fn main() {
Expand Down Expand Up @@ -118,5 +120,6 @@ fn try_main() -> anyhow::Result<()> {
Commands::Setup(task) => task.run(ctx),
Commands::Install(task) => task.run(ctx),
Commands::RustupComponentAdd(task) => task.run(ctx),
Commands::ValidateMembers(task) => task.run(ctx),
}
}
10 changes: 10 additions & 0 deletions xtask/src/precheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::integration_tests;
use crate::nextest::Nextest;
use crate::nextest_report::NextestReport;
use crate::setup::Setup;
use crate::validate_members::ValidateMembers;
use crate::Xtask;
use crate::XtaskCtx;

Expand All @@ -31,6 +32,9 @@ struct Stage {
/// Run copyright checks
#[clap(long)]
copyright: bool,
/// Run validate members checks
#[clap(long)]
validate_members: bool,
/// Run audit checks
#[clap(long)]
audit: bool,
Expand Down Expand Up @@ -100,6 +104,7 @@ impl Xtask for Precheck {
let stage = self.stage.unwrap_or(Stage {
setup: true,
copyright: true,
validate_members: true,
audit: true,
fmt: true,
clippy: true,
Expand Down Expand Up @@ -137,6 +142,11 @@ impl Xtask for Precheck {
Copyright { fix: false }.run(ctx.clone())?;
}

// Run ValidateMembers
if stage.validate_members || stage.all {
ValidateMembers { fix: false }.run(ctx.clone())?;
}

// Run Audit
if (stage.audit || stage.all) && !self.skip_audit {
Audit {}.run(ctx.clone())?;
Expand Down
95 changes: 95 additions & 0 deletions xtask/src/validate_members.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#![warn(missing_docs)]
#![forbid(unsafe_code)]

//! Xtask to validate that all path dependencies in the workspace are also listed as workspace members

use std::fs;

use clap::Parser;
use toml_edit::DocumentMut;
use toml_edit::Value;

use crate::Xtask;
use crate::XtaskCtx;

/// Xtask to validate that all path dependencies in the workspace are also listed as workspace members
#[derive(Parser)]
#[clap(
about = "Validate that all path dependencies in the workspace are also listed as workspace members"
)]
pub struct ValidateMembers {
/// Attempt to fix any missing workspace members
#[clap(long)]
pub fix: bool,
}

impl Xtask for ValidateMembers {
fn run(self, _ctx: XtaskCtx) -> anyhow::Result<()> {
log::trace!("running validate_members");

// read workspace Cargo.toml and parse into toml_edit DocumentMut
let data: Vec<u8> = fs::read("Cargo.toml")?;
let data_str = std::str::from_utf8(&data)?;
let mut doc = data_str.parse::<DocumentMut>()?;

// get workspace members from doc
let members = doc["workspace"]["members"].as_array().unwrap().clone();
let mut member_paths: Vec<&str> = Vec::new();
for value in members.iter() {
member_paths.push(value.as_str().unwrap());
}
Comment thread
zimmy87 marked this conversation as resolved.

// get internal dependency paths from doc
let mut dep_paths: Vec<&str> = Vec::new();
let dep_table = doc["workspace"]["dependencies"].as_table().unwrap().clone();
for (_dep_str, dep_val) in dep_table.iter() {
if dep_val.is_inline_table() {
if dep_val.as_inline_table().unwrap().contains_key("path") {
dep_paths.push(dep_val.as_inline_table().unwrap()["path"].as_str().unwrap());
}
}
}

// filter dep_paths to those not in member_paths
let mut non_member_paths: Vec<&str> = Vec::new();
for dep_path in &dep_paths {
if !member_paths.iter().any(|m| dep_path.starts_with(m)) {
non_member_paths.push(dep_path);
}
Comment thread
zimmy87 marked this conversation as resolved.
}

if self.fix {
// update workspace members to include any missing paths
let mut updated = false;
for dep_path in &dep_paths {
if !member_paths.iter().any(|m| dep_path.starts_with(m)) {
log::trace!("Adding missing workspace member: {}", dep_path);
doc["workspace"]["members"]
.as_array_mut()
.unwrap()
.push(Value::from(*dep_path));
updated = true;
}
}

if updated {
fs::write("Cargo.toml", doc.to_string())?;
}
} else {
if !non_member_paths.is_empty() {
Comment thread
zimmy87 marked this conversation as resolved.
Outdated
// Error
Err(anyhow::anyhow!(
"Workspace members missing path dependencies: {:?}",
non_member_paths
))?
}
}

log::trace!("done validate_members");

Ok(())
}
}