Skip to content
Merged
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
1 change: 1 addition & 0 deletions src/cli/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ fn build_orchestrator_config(
show_full_output: args.shared.show_full_output,
poll_results_options,
extra_env: HashMap::new(),
fair_sched: args.shared.experimental.experimental_fair_sched,
})
}

Expand Down
53 changes: 53 additions & 0 deletions src/cli/experimental.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use crate::local_logger::icons::Icon;
use clap::Args;
use console::style;

/// Experimental flags that may change or be removed without notice.
///
/// These flags are under active development and their behavior is not guaranteed
/// to remain stable across releases.
#[derive(Args, Debug, Clone)]
pub struct ExperimentalArgs {
/// Enable valgrind's --fair-sched option.
#[arg(
long,
default_value_t = false,
help_heading = "Experimental",
env = "CODSPEED_EXPERIMENTAL_FAIR_SCHED"
)]
pub experimental_fair_sched: bool,
}

impl ExperimentalArgs {
/// Returns the names of all experimental flags that were explicitly set by the user.
pub fn active_flags(&self) -> Vec<&'static str> {
let mut flags = Vec::new();
if self.experimental_fair_sched {
flags.push("--experimental-fair-sched");
}
flags
}

/// If any experimental flags are active, prints a warning to stderr.
pub fn warn_if_active(&self) {
let flags = self.active_flags();
if flags.is_empty() {
return;
}

let flag_list = flags
.iter()
.map(|f| style(*f).bold().to_string())
.collect::<Vec<_>>()
.join(", ");

eprintln!(
"\n {} Experimental flags enabled: {}\n \
These may change or be removed without notice.\n \
Share feedback at {}.\n",
style(Icon::Warning.to_string()).yellow(),
flag_list,
style("https://github.com/CodSpeedHQ/codspeed/issues").underlined(),
);
}
}
28 changes: 27 additions & 1 deletion src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod auth;
pub(crate) mod exec;
pub(crate) mod experimental;
pub(crate) mod run;
mod setup;
mod shared;
Expand All @@ -15,14 +16,35 @@ use std::path::PathBuf;
use crate::{
api_client::CodSpeedAPIClient,
config::CodSpeedConfig,
local_logger::{CODSPEED_U8_COLOR_CODE, init_local_logger},
local_logger::{CODSPEED_U8_COLOR_CODE, IS_TTY, init_local_logger},
prelude::*,
project_config::DiscoveredProjectConfig,
};
use clap::{
Parser, Subcommand,
builder::{Styles, styling},
};
use console::Term;

/// Guard that hides the terminal cursor on creation and restores it on drop.
struct CursorGuard;

impl CursorGuard {
fn new() -> Self {
if *IS_TTY {
let _ = Term::stderr().hide_cursor();
}
Self
}
}

impl Drop for CursorGuard {
fn drop(&mut self) {
if *IS_TTY {
let _ = Term::stderr().show_cursor();
}
}
}

fn create_styles() -> Styles {
styling::Styles::styled()
Expand Down Expand Up @@ -99,6 +121,8 @@ enum Commands {

pub async fn run() -> Result<()> {
let cli = Cli::parse();
// Important: keep this after the Cli::parse() because the function can exit the process by itself, skipping the drop of the CursorGuard
let _cursor_guard = CursorGuard::new();
let codspeed_config =
CodSpeedConfig::load_with_override(cli.config_name.as_deref(), cli.oauth_token.as_deref())?;
let api_client = CodSpeedAPIClient::try_from((&cli, &codspeed_config))?;
Expand All @@ -125,6 +149,7 @@ pub async fn run() -> Result<()> {

match cli.command {
Commands::Run(args) => {
args.shared.experimental.warn_if_active();
run::run(
*args,
&api_client,
Expand All @@ -135,6 +160,7 @@ pub async fn run() -> Result<()> {
.await?
}
Commands::Exec(args) => {
args.shared.experimental.warn_if_active();
exec::run(
*args,
&api_client,
Expand Down
5 changes: 5 additions & 0 deletions src/cli/run/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl RunArgs {
/// Constructs a new `RunArgs` with default values for testing purposes
pub fn test() -> Self {
use super::PerfRunArgs;
use super::experimental::ExperimentalArgs;
use crate::RunnerMode;

Self {
Expand All @@ -72,6 +73,9 @@ impl RunArgs {
enable_perf: false,
perf_unwinding_mode: None,
},
experimental: ExperimentalArgs {
experimental_fair_sched: false,
},
},
instruments: vec![],
mongo_uri_env_name: None,
Expand Down Expand Up @@ -119,6 +123,7 @@ fn build_orchestrator_config(
show_full_output: args.shared.show_full_output,
poll_results_options,
extra_env: HashMap::new(),
fair_sched: args.shared.experimental.experimental_fair_sched,
})
}

Expand Down
4 changes: 4 additions & 0 deletions src/cli/shared.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::experimental::ExperimentalArgs;
use crate::VERSION;
use crate::executor::config::SimulationTool;
use crate::local_logger::CODSPEED_U8_COLOR_CODE;
Expand Down Expand Up @@ -116,6 +117,9 @@ pub struct ExecAndRunSharedArgs {

#[command(flatten)]
pub perf_run_args: PerfRunArgs,

#[command(flatten)]
pub experimental: ExperimentalArgs,
}

impl ExecAndRunSharedArgs {
Expand Down
6 changes: 6 additions & 0 deletions src/executor/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub struct OrchestratorConfig {
pub poll_results_options: PollResultsOptions,
/// Additional environment variables forwarded to executor subprocesses.
pub extra_env: HashMap<String, String>,
/// Enable valgrind's --fair-sched option.
pub fair_sched: bool,
}

/// Per-execution configuration passed to executors.
Expand Down Expand Up @@ -111,6 +113,8 @@ pub struct ExecutorConfig {
/// Whether to enable language-level introspection (Node.js, Go wrappers in PATH).
/// Disabled for exec-harness targets since they don't need it.
pub enable_introspection: bool,
/// Enable valgrind's --fair-sched option.
pub fair_sched: bool,
}

#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -186,6 +190,7 @@ impl OrchestratorConfig {
go_runner_version: self.go_runner_version.clone(),
extra_env: self.extra_env.clone(),
enable_introspection,
fair_sched: self.fair_sched,
}
}
}
Expand Down Expand Up @@ -223,6 +228,7 @@ impl OrchestratorConfig {
show_full_output: false,
poll_results_options: PollResultsOptions::new(false, None),
extra_env: HashMap::new(),
fair_sched: false,
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/executor/valgrind/measure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::{env::consts::ARCH, process::Command};
use tempfile::TempPath;

/// Builds the Valgrind argument list for the given simulation tool.
fn get_valgrind_args(tool: &SimulationTool) -> Vec<String> {
fn get_valgrind_args(tool: &SimulationTool, config: &ExecutorConfig) -> Vec<String> {
let mut args: Vec<String> = [
"-q",
"--trace-children=yes",
Expand Down Expand Up @@ -50,6 +50,11 @@ fn get_valgrind_args(tool: &SimulationTool) -> Vec<String> {
"--trace-children-skip={}",
children_skip_patterns.join(",")
));

if config.fair_sched {
args.push("--fair-sched=yes".to_string());
}

args
}

Expand Down Expand Up @@ -114,7 +119,7 @@ pub async fn measure(
cmd.current_dir(abs_cwd);
}
// Configure valgrind
let valgrind_args = get_valgrind_args(&config.simulation_tool);
let valgrind_args = get_valgrind_args(&config.simulation_tool, config);
let log_path = profile_folder.join("valgrind.log");
cmd.arg("valgrind").args(valgrind_args.iter());
if config.simulation_tool == SimulationTool::Callgrind {
Expand Down
19 changes: 1 addition & 18 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,9 @@
use codspeed_runner::{clean_logger, cli};
use console::{Term, style};
use console::style;
use log::log_enabled;

struct HiddenCursor(Term);

impl HiddenCursor {
fn new() -> Self {
let term = Term::stderr();
let _ = term.hide_cursor();
Self(term)
}
}

impl Drop for HiddenCursor {
fn drop(&mut self) {
let _ = self.0.show_cursor();
}
}

#[tokio::main(flavor = "current_thread")]
async fn main() {
let _cursor = HiddenCursor::new();
let res = cli::run().await;
if let Err(err) = res {
// Show the primary error
Expand Down
Loading