Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
83 changes: 83 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ test-with = { version = "0.15", default-features = false, features = [] }
rstest = { version = "0.25.0", default-features = false }
rstest_reuse = "0.7.0"
shell-quote = "0.7.2"
assert_cmd = "2.0.16"
predicates = "3.1.4"

[workspace]
members = [
Expand Down
4 changes: 0 additions & 4 deletions src/cli/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ impl ExecArgs {
/// CLI arguments take precedence over config values.
pub fn merge_with_project_config(mut self, project_config: Option<&ProjectConfig>) -> Self {
if let Some(project_config) = project_config {
// Merge shared args
self.shared =
ConfigMerger::merge_shared_args(&self.shared, project_config.options.as_ref());
// Merge walltime args
self.walltime_args = ConfigMerger::merge_walltime_options(
&self.walltime_args,
project_config
Expand Down
14 changes: 8 additions & 6 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
config::CodSpeedConfig,
local_logger::{CODSPEED_U8_COLOR_CODE, init_local_logger},
prelude::*,
project_config::ProjectConfig,
project_config::DiscoveredProjectConfig,
};
use clap::{
Parser, Subcommand,
Expand Down Expand Up @@ -97,9 +97,11 @@ pub async fn run() -> Result<()> {
CodSpeedConfig::load_with_override(cli.config_name.as_deref(), cli.oauth_token.as_deref())?;
let api_client = CodSpeedAPIClient::try_from((&cli, &codspeed_config))?;

// Discover project configuration file (this may change the working directory)
let project_config =
ProjectConfig::discover_and_load(cli.config.as_deref(), &std::env::current_dir()?)?;
// Discover project configuration file
let discovered_config = DiscoveredProjectConfig::discover_and_load(
cli.config.as_deref(),
&std::env::current_dir()?,
)?;

// In the context of the CI, it is likely that a ~ made its way here without being expanded by the shell
let setup_cache_dir = cli
Expand All @@ -121,7 +123,7 @@ pub async fn run() -> Result<()> {
*args,
&api_client,
&codspeed_config,
project_config.as_ref(),
discovered_config.as_ref(),
setup_cache_dir,
)
.await?
Expand All @@ -131,7 +133,7 @@ pub async fn run() -> Result<()> {
*args,
&api_client,
&codspeed_config,
project_config.as_ref(),
discovered_config.as_ref().map(|d| &d.config),
setup_cache_dir,
)
.await?
Expand Down
60 changes: 41 additions & 19 deletions src/cli/run/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use crate::executor;
use crate::executor::config::{self, OrchestratorConfig, RepositoryOverride};
use crate::instruments::Instruments;
use crate::prelude::*;
use crate::project_config::ProjectConfig;
use crate::project_config::merger::ConfigMerger;
use crate::project_config::DiscoveredProjectConfig;
use crate::run_environment::interfaces::RepositoryProvider;
use crate::upload::poll_results::PollResultsOptions;
use clap::{Args, ValueEnum};
Expand Down Expand Up @@ -40,19 +39,6 @@ pub struct RunArgs {
pub command: Vec<String>,
}

impl RunArgs {
/// Merge CLI args with project config if available
///
/// CLI arguments take precedence over config values.
pub fn merge_with_project_config(mut self, project_config: Option<&ProjectConfig>) -> Self {
if let Some(project_config) = project_config {
self.shared =
ConfigMerger::merge_shared_args(&self.shared, project_config.options.as_ref());
}
self
}
}

#[derive(ValueEnum, Clone, Debug, PartialEq)]
pub enum MessageFormat {
Json,
Expand Down Expand Up @@ -152,12 +138,11 @@ pub async fn run(
args: RunArgs,
api_client: &CodSpeedAPIClient,
codspeed_config: &CodSpeedConfig,
project_config: Option<&ProjectConfig>,
discovered_config: Option<&DiscoveredProjectConfig>,
setup_cache_dir: Option<&Path>,
) -> Result<()> {
let output_json = args.message_format == Some(MessageFormat::Json);

let args = args.merge_with_project_config(project_config);
let project_config = discovered_config.map(|d| &d.config);

let run_target = if args.command.is_empty() {
// No command provided - check for targets in project config
Expand All @@ -183,6 +168,8 @@ pub async fn run(

match run_target {
RunTarget::SingleCommand(args) => {
// SingleCommand: working_directory comes from --working-directory CLI flag only.
// Config file's working-directory is NOT used.
let command = args.command.join(" ");
let config = build_orchestrator_config(
args,
Expand All @@ -192,6 +179,7 @@ pub async fn run(
}],
PollResultsOptions::for_run(output_json),
)?;

let orchestrator =
executor::Orchestrator::new(config, codspeed_config, api_client).await?;

Expand All @@ -208,10 +196,44 @@ pub async fn run(
targets,
default_walltime,
} => {
// ConfigTargets: working_directory is resolved relative to config file dir.
// If --working-directory CLI flag is passed, ignore it with a warning.
if args.shared.working_directory.is_some() {
// Intentionally using eprintln! because logger has not been initialized yet.
eprintln!(
"Warning: The --working-directory flag is ignored when running targets from the config file. \
Use the `working-directory` option in the config file instead."
);
}

// Resolve working_directory relative to config file directory
let resolved_working_directory =
if let Some(config_dir) = discovered_config.and_then(|d| d.config_dir()) {
let root_wd = project_config
.and_then(|c| c.options.as_ref())
.and_then(|o| o.working_directory.as_ref());

match root_wd {
Some(wd) => {
let wd_path = Path::new(wd);
if wd_path.is_absolute() {
Some(wd.clone())
} else {
Some(config_dir.join(wd).to_string_lossy().into_owned())
}
}
None => Some(config_dir.to_string_lossy().into_owned()),
}
} else {
None
};

let benchmark_targets =
super::exec::multi_targets::build_benchmark_targets(targets, default_walltime)?;
let config =
let mut config =
build_orchestrator_config(args, benchmark_targets, PollResultsOptions::for_exec())?;
config.working_directory = resolved_working_directory;

super::exec::execute_config(config, api_client, codspeed_config, setup_cache_dir)
.await?;
}
Expand Down
5 changes: 1 addition & 4 deletions src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub async fn run_executor(
None
};

let run_result = executor.run(execution_context, &mongo_tracer).await;
executor.run(execution_context, &mongo_tracer).await?;

// TODO: refactor and move directly in the Instruments struct as a `stop` method
if let Some(mut mongo_tracer) = mongo_tracer {
Expand All @@ -123,9 +123,6 @@ pub async fn run_executor(
debug!("Tearing down the executor");
executor.teardown(execution_context).await?;

// Propagate any run error after cleanup
run_result?;

orchestrator
.logger
.persist_log_to_profile_folder(&execution_context.profile_folder)?;
Expand Down
1 change: 0 additions & 1 deletion src/executor/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,6 @@ fi
// Unset GITHUB_ACTIONS to force LocalProvider which supports repository_override
temp_env::async_with_vars(&[("GITHUB_ACTIONS", None::<&str>)], async {
let config = walltime_config(&wrapped_command, true);
dbg!(&config);
let (execution_context, _temp_dir) = create_test_setup(config).await;
executor.run(&execution_context, &None).await.unwrap();
})
Expand Down
Loading
Loading