Skip to content

Commit

Permalink
organize cli commands and imports
Browse files Browse the repository at this point in the history
  • Loading branch information
dfrankland committed Dec 27, 2024
1 parent 8ccfe22 commit e95f9d6
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 196 deletions.
8 changes: 4 additions & 4 deletions cli/src/api_client/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use anyhow::Context;
use http::{header::HeaderMap, HeaderValue};
use reqwest::{header, Client, Response, StatusCode};
use std::path::Path;
use tokio::fs;

use anyhow::Context;
use api;
use call_api::CallApi;
use constants::{DEFAULT_ORIGIN, TRUNK_PUBLIC_API_ADDRESS_ENV};
use http::{header::HeaderMap, HeaderValue};
use reqwest::{header, Client, Response, StatusCode};
use tokio::fs;

mod call_api;

Expand Down
1 change: 1 addition & 0 deletions cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ pub mod api_client;
pub mod print;
pub mod runner;
pub mod scanner;
pub mod test;
pub mod upload;
pub mod validate;
182 changes: 7 additions & 175 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
use std::env;
use std::io::Write;
use std::{env, io::Write};

use clap::{Parser, Subcommand};
use constants::SENTRY_DSN;

use bundle::RunResult;
use clap::{Args, Parser, Subcommand};
use codeowners::CodeOwners;
use constants::{EXIT_FAILURE, SENTRY_DSN};
use context::{
bazel_bep::parser::BazelBepParser, junit::junit_path::JunitReportFileWithStatus,
repo::BundleRepo,
};
use trunk_analytics_cli::{
api_client::ApiClient,
print::print_bep_results,
runner::{run_quarantine, run_test_command, JunitSpec},
test::{run_test, TestArgs},
upload::{run_upload, UploadArgs},
validate::validate,
validate::{run_validate, ValidateArgs},
};

#[derive(Debug, Parser)]
Expand All @@ -29,42 +21,6 @@ struct Cli {
pub command: Commands,
}

#[derive(Args, Clone, Debug)]
struct TestArgs {
#[command(flatten)]
upload_args: UploadArgs,
#[arg(
required = true,
allow_hyphen_values = true,
trailing_var_arg = true,
help = "Test command to invoke."
)]
command: Vec<String>,
}

#[derive(Args, Clone, Debug)]
struct ValidateArgs {
#[arg(
long,
required_unless_present = "bazel_bep_path",
conflicts_with = "bazel_bep_path",
value_delimiter = ',',
value_parser = clap::builder::NonEmptyStringValueParser::new(),
help = "Comma-separated list of glob paths to junit files."
)]
junit_paths: Vec<String>,
#[arg(
long,
required_unless_present = "junit_paths",
help = "Path to bazel build event protocol JSON file."
)]
bazel_bep_path: Option<String>,
#[arg(long, help = "Show warning-level log messages in output.")]
show_warnings: bool,
#[arg(long, help = "Value to override CODEOWNERS file or directory path.")]
pub codeowners_path: Option<String>,
}

#[derive(Debug, Subcommand)]
enum Commands {
/// Upload data to Trunk Flaky Tests
Expand Down Expand Up @@ -110,110 +66,6 @@ fn main() -> anyhow::Result<()> {
})
}

async fn run_test(test_args: TestArgs) -> anyhow::Result<i32> {
let TestArgs {
command,
upload_args,
} = test_args;
let UploadArgs {
junit_paths,
bazel_bep_path,
org_url_slug,
token,
repo_root,
repo_url,
repo_head_sha,
repo_head_branch,
repo_head_commit_epoch,
use_quarantining,
team,
codeowners_path,
..
} = &upload_args;

let repo = BundleRepo::new(
repo_root.clone(),
repo_url.clone(),
repo_head_sha.clone(),
repo_head_branch.clone(),
repo_head_commit_epoch.clone(),
)?;

if junit_paths.is_empty() && bazel_bep_path.is_none() {
return Err(anyhow::anyhow!("No junit paths provided."));
}

let api_client = ApiClient::new(String::from(token))?;

let codeowners = CodeOwners::find_file(&repo.repo_root, codeowners_path);
let junit_spec = if !junit_paths.is_empty() {
JunitSpec::Paths(junit_paths.clone())
} else {
JunitSpec::BazelBep(bazel_bep_path.as_deref().unwrap_or_default().to_string())
};

log::info!("running command: {:?}", command);
let run_result = run_test_command(
&repo,
&org_url_slug,
command.first().unwrap(),
command.iter().skip(1).collect(),
junit_spec,
team.clone(),
&codeowners,
)
.await
.unwrap_or_else(|e| {
log::error!("Test command failed to run: {}", e);
RunResult {
exit_code: EXIT_FAILURE,
failures: Vec::new(),
exec_start: None,
}
});

let run_exit_code = run_result.exit_code;
let failures = run_result.failures;

let quarantine_run_result = if *use_quarantining {
Some(
run_quarantine(
&api_client,
&api::GetQuarantineBulkTestStatusRequest {
repo: repo.repo,
org_url_slug: org_url_slug.clone(),
test_identifiers: failures.clone(),
},
failures,
run_exit_code,
)
.await,
)
} else {
None
};

let exit_code = quarantine_run_result
.as_ref()
.map(|r| r.exit_code)
.unwrap_or(run_exit_code);

let exec_start = run_result.exec_start;
if let Err(e) = run_upload(
upload_args,
Some(command.join(" ")),
None, // don't re-run quarantine checks
codeowners,
exec_start,
)
.await
{
log::error!("Error uploading test results: {:?}", e)
};

Ok(exit_code)
}

async fn run(cli: Cli) -> anyhow::Result<i32> {
match cli.command {
Commands::Upload(upload_args) => {
Expand All @@ -222,28 +74,8 @@ async fn run(cli: Cli) -> anyhow::Result<i32> {
}
Commands::Test(test_args) => run_test(test_args).await,
Commands::Validate(validate_args) => {
let ValidateArgs {
junit_paths,
bazel_bep_path,
show_warnings,
codeowners_path,
} = validate_args;

print_cli_start_info();

let junit_file_paths = match bazel_bep_path {
Some(bazel_bep_path) => {
let mut parser = BazelBepParser::new(bazel_bep_path);
let bep_result = parser.parse()?;
print_bep_results(&bep_result);
bep_result.uncached_xml_files()
}
None => junit_paths
.into_iter()
.map(JunitReportFileWithStatus::from)
.collect(),
};
validate(junit_file_paths, show_warnings, codeowners_path).await
run_validate(validate_args).await
}
}
}
Expand Down
10 changes: 6 additions & 4 deletions cli/src/runner.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use quick_junit::TestCaseStatus;
use std::collections::HashMap;
use std::process::{Command, Stdio};
use std::time::SystemTime;
use std::{
collections::HashMap,
process::{Command, Stdio},
time::SystemTime,
};

use api;
use bundle::{
Expand All @@ -17,6 +18,7 @@ use context::{
},
repo::BundleRepo,
};
use quick_junit::TestCaseStatus;

use crate::{api_client::ApiClient, print::print_bep_results};

Expand Down
128 changes: 128 additions & 0 deletions cli/src/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
use bundle::RunResult;
use clap::Args;
use codeowners::CodeOwners;
use constants::EXIT_FAILURE;
use context::repo::BundleRepo;

use crate::{
api_client::ApiClient,
runner::{run_quarantine, run_test_command, JunitSpec},
upload::{run_upload, UploadArgs},
};

#[derive(Args, Clone, Debug)]
pub struct TestArgs {
#[command(flatten)]
upload_args: UploadArgs,
#[arg(
required = true,
allow_hyphen_values = true,
trailing_var_arg = true,
help = "Test command to invoke."
)]
command: Vec<String>,
}

pub async fn run_test(test_args: TestArgs) -> anyhow::Result<i32> {
let TestArgs {
command,
upload_args,
} = test_args;
let UploadArgs {
junit_paths,
bazel_bep_path,
org_url_slug,
token,
repo_root,
repo_url,
repo_head_sha,
repo_head_branch,
repo_head_commit_epoch,
use_quarantining,
team,
codeowners_path,
..
} = &upload_args;

let repo = BundleRepo::new(
repo_root.clone(),
repo_url.clone(),
repo_head_sha.clone(),
repo_head_branch.clone(),
repo_head_commit_epoch.clone(),
)?;

if junit_paths.is_empty() && bazel_bep_path.is_none() {
return Err(anyhow::anyhow!("No junit paths provided."));
}

let api_client = ApiClient::new(String::from(token))?;

let codeowners = CodeOwners::find_file(&repo.repo_root, codeowners_path);
let junit_spec = if !junit_paths.is_empty() {
JunitSpec::Paths(junit_paths.clone())
} else {
JunitSpec::BazelBep(bazel_bep_path.as_deref().unwrap_or_default().to_string())
};

log::info!("running command: {:?}", command);
let run_result = run_test_command(
&repo,
org_url_slug,
command.first().unwrap(),
command.iter().skip(1).collect(),
junit_spec,
team.clone(),
&codeowners,
)
.await
.unwrap_or_else(|e| {
log::error!("Test command failed to run: {}", e);
RunResult {
exit_code: EXIT_FAILURE,
failures: Vec::new(),
exec_start: None,
}
});

let run_exit_code = run_result.exit_code;
let failures = run_result.failures;

let quarantine_run_result = if *use_quarantining {
Some(
run_quarantine(
&api_client,
&api::GetQuarantineBulkTestStatusRequest {
repo: repo.repo,
org_url_slug: org_url_slug.clone(),
test_identifiers: failures.clone(),
},
failures,
run_exit_code,
)
.await,
)
} else {
None
};

let exit_code = quarantine_run_result
.as_ref()
.map(|r| r.exit_code)
.unwrap_or(run_exit_code);

let exec_start = run_result.exec_start;
if let Err(e) = run_upload(
upload_args,
Some(command.join(" ")),
None, // don't re-run quarantine checks
codeowners,
exec_start,
)
.await
{
log::error!("Error uploading test results: {:?}", e)
};

Ok(exit_code)
}
Loading

0 comments on commit e95f9d6

Please sign in to comment.