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
11 changes: 9 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ pub struct Cli {
#[arg(long, env = "CODSPEED_OAUTH_TOKEN", global = true, hide = true)]
pub oauth_token: Option<String>,

/// The configuration name to use
/// If provided, the configuration will be loaded from ~/.config/codspeed/{config-name}.yaml
/// Otherwise, loads from ~/.config/codspeed/config.yaml
#[arg(long, env = "CODSPEED_CONFIG_NAME", global = true)]
pub config_name: Option<String>,

/// The directory to use for caching installed tools
/// The runner will restore cached tools from this directory before installing them.
/// After successful installation, the runner will cache the installed tools to this directory.
Expand All @@ -63,7 +69,8 @@ enum Commands {

pub async fn run() -> Result<()> {
let cli = Cli::parse();
let codspeed_config = CodSpeedConfig::load_with_override(cli.oauth_token.as_deref())?;
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))?;
// 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 @@ -83,7 +90,7 @@ pub async fn run() -> Result<()> {
Commands::Run(args) => {
run::run(args, &api_client, &codspeed_config, setup_cache_dir).await?
}
Commands::Auth(args) => auth::run(args, &api_client).await?,
Commands::Auth(args) => auth::run(args, &api_client, cli.config_name.as_deref()).await?,
Commands::Setup => setup::setup(setup_cache_dir).await?,
}
Ok(())
Expand Down
14 changes: 9 additions & 5 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@ enum AuthCommands {
Login,
}

pub async fn run(args: AuthArgs, api_client: &CodSpeedAPIClient) -> Result<()> {
pub async fn run(
args: AuthArgs,
api_client: &CodSpeedAPIClient,
config_name: Option<&str>,
) -> Result<()> {
match args.command {
AuthCommands::Login => login(api_client).await?,
AuthCommands::Login => login(api_client, config_name).await?,
}
Ok(())
}

const LOGIN_SESSION_MAX_DURATION: Duration = Duration::from_secs(60 * 5); // 5 minutes

async fn login(api_client: &CodSpeedAPIClient) -> Result<()> {
async fn login(api_client: &CodSpeedAPIClient, config_name: Option<&str>) -> Result<()> {
debug!("Login to CodSpeed");
start_group!("Creating login session");
let login_session_payload = api_client.create_login_session().await?;
Expand Down Expand Up @@ -67,9 +71,9 @@ async fn login(api_client: &CodSpeedAPIClient) -> Result<()> {
}
end_group!();

let mut config = CodSpeedConfig::load()?;
let mut config = CodSpeedConfig::load_with_override(config_name, None)?;
config.auth.token = Some(token);
config.persist()?;
config.persist(config_name)?;
debug!("Token saved to configuration file");

info!("Login successful, your are now authenticated on CodSpeed");
Expand Down
36 changes: 21 additions & 15 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,22 @@ nest! {

/// Get the path to the configuration file, following the XDG Base Directory Specification
/// at https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
fn get_configuration_file_path() -> PathBuf {
///
/// If config_name is None, returns ~/.config/codspeed/config.yaml (default)
/// If config_name is Some, returns ~/.config/codspeed/{config_name}.yaml
fn get_configuration_file_path(config_name: Option<&str>) -> PathBuf {
let config_dir = env::var("XDG_CONFIG_HOME")
.map(PathBuf::from)
.unwrap_or_else(|_| {
let home = env::var("HOME").expect("HOME env variable not set");
PathBuf::from(home).join(".config")
});
let config_dir = config_dir.join("codspeed");
config_dir.join("config.yaml")

match config_name {
Some(name) => config_dir.join(format!("{name}.yaml")),
None => config_dir.join("config.yaml"),
}
}

impl Default for CodSpeedConfig {
Expand All @@ -40,15 +47,19 @@ impl CodSpeedConfig {
///
/// If oauth_token_override is provided, the token from the loaded configuration will be
/// ignored, and the override will be used instead
pub fn load_with_override(oauth_token_override: Option<&str>) -> Result<Self> {
let config_path = get_configuration_file_path();
pub fn load_with_override(
config_name: Option<&str>,
oauth_token_override: Option<&str>,
) -> Result<Self> {
let config_path = get_configuration_file_path(config_name);

let mut config = match fs::read(&config_path) {
Ok(config_str) => {
let config = serde_yaml::from_slice(&config_str).context(format!(
"Failed to parse CodSpeed config at {}",
config_path.display()
))?;
let config: CodSpeedConfig =
serde_yaml::from_slice(&config_str).context(format!(
"Failed to parse CodSpeed config at {}",
config_path.display()
))?;
debug!("Config loaded from {}", config_path.display());
config
}
Expand All @@ -66,14 +77,9 @@ impl CodSpeedConfig {
Ok(config)
}

/// Load the configuration. If it does not exist, return a default configuration.
pub fn load() -> Result<Self> {
Self::load_with_override(None)
}

/// Persist changes to the configuration
pub fn persist(&self) -> Result<()> {
let config_path = get_configuration_file_path();
pub fn persist(&self, config_name: Option<&str>) -> Result<()> {
let config_path = get_configuration_file_path(config_name);
fs::create_dir_all(config_path.parent().unwrap())?;

let config_str = serde_yaml::to_string(self)?;
Expand Down
Loading