feat: refactor frontend configuration
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
71
crates/cuddle-please-frontend/src/gatheres/cli.rs
Normal file
71
crates/cuddle-please-frontend/src/gatheres/cli.rs
Normal file
@@ -0,0 +1,71 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Args;
|
||||
|
||||
use crate::stage0_config::{
|
||||
PleaseConfigBuilder, PleaseProjectConfigBuilder, PleaseSettingsConfigBuilder,
|
||||
};
|
||||
|
||||
#[derive(Args, Debug, Clone)]
|
||||
pub struct ConfigArgs {
|
||||
/// Which repository to publish against. If not supplied remote url will be inferred from environment or fail if not present.
|
||||
#[arg(
|
||||
env = "CUDDLE_PLEASE_API_URL",
|
||||
long,
|
||||
global = true,
|
||||
help_heading = "Config"
|
||||
)]
|
||||
pub api_url: Option<String>,
|
||||
|
||||
/// repo is the name of repository you want to release for
|
||||
#[arg(
|
||||
env = "CUDDLE_PLEASE_REPO",
|
||||
long,
|
||||
global = true,
|
||||
help_heading = "Config"
|
||||
)]
|
||||
pub repo: Option<String>,
|
||||
|
||||
/// owner is the name of user from which the repository belongs <user>/<repo>
|
||||
#[arg(
|
||||
env = "CUDDLE_PLEASE_OWNER",
|
||||
long,
|
||||
global = true,
|
||||
help_heading = "Config"
|
||||
)]
|
||||
pub owner: Option<String>,
|
||||
|
||||
/// which source directory to use, if not set `std::env::current_dir` is used instead.
|
||||
#[arg(
|
||||
env = "CUDDLE_PLEASE_SOURCE",
|
||||
long,
|
||||
global = true,
|
||||
help_heading = "Config"
|
||||
)]
|
||||
pub source: Option<PathBuf>,
|
||||
|
||||
/// which branch is being run from
|
||||
#[arg(
|
||||
env = "CUDDLE_PLEASE_BRANCH",
|
||||
long,
|
||||
global = true,
|
||||
help_heading = "Config"
|
||||
)]
|
||||
pub branch: Option<String>,
|
||||
}
|
||||
|
||||
impl From<ConfigArgs> for PleaseConfigBuilder {
|
||||
fn from(value: ConfigArgs) -> Self {
|
||||
Self {
|
||||
project: Some(PleaseProjectConfigBuilder {
|
||||
owner: value.owner,
|
||||
repository: value.repo,
|
||||
source: value.source,
|
||||
branch: value.branch,
|
||||
}),
|
||||
settings: Some(PleaseSettingsConfigBuilder {
|
||||
api_url: value.api_url,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
80
crates/cuddle-please-frontend/src/gatheres/config_file.rs
Normal file
80
crates/cuddle-please-frontend/src/gatheres/config_file.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
|
||||
use crate::stage0_config::PleaseConfigBuilder;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct CuddleEmbeddedPleaseConfig {
|
||||
please: PleaseConfigBuilder,
|
||||
}
|
||||
|
||||
impl From<CuddleEmbeddedPleaseConfig> for PleaseConfigBuilder {
|
||||
fn from(value: CuddleEmbeddedPleaseConfig) -> Self {
|
||||
value.please
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct CuddlePleaseConfig {
|
||||
#[serde(flatten)]
|
||||
please: PleaseConfigBuilder,
|
||||
}
|
||||
impl From<CuddlePleaseConfig> for PleaseConfigBuilder {
|
||||
fn from(value: CuddlePleaseConfig) -> Self {
|
||||
value.please
|
||||
}
|
||||
}
|
||||
|
||||
const CUDDLE_FILE_NAME: &str = "cuddle";
|
||||
const CUDDLE_CONFIG_FILE_NAME: &str = "cuddle.please";
|
||||
const YAML_EXTENSION: &str = "yaml";
|
||||
|
||||
pub fn get_config_from_config_file(current_dir: &Path) -> PleaseConfigBuilder {
|
||||
let current_cuddle_path = current_dir
|
||||
.clone()
|
||||
.join(format!("{CUDDLE_FILE_NAME}.{YAML_EXTENSION}"));
|
||||
let current_cuddle_config_path = current_dir
|
||||
.clone()
|
||||
.join(format!("{CUDDLE_CONFIG_FILE_NAME}.{YAML_EXTENSION}"));
|
||||
let mut please_config = PleaseConfigBuilder::default();
|
||||
|
||||
if let Some(config) = get_config_from_file::<CuddleEmbeddedPleaseConfig>(current_cuddle_path) {
|
||||
please_config = please_config.merge(&config).clone();
|
||||
}
|
||||
|
||||
if let Some(config) = get_config_from_file::<CuddlePleaseConfig>(current_cuddle_config_path) {
|
||||
please_config = please_config.merge(&config).clone();
|
||||
}
|
||||
|
||||
please_config
|
||||
}
|
||||
|
||||
pub fn get_config_from_file<T>(current_cuddle_path: PathBuf) -> Option<PleaseConfigBuilder>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
T: Into<PleaseConfigBuilder>,
|
||||
{
|
||||
match std::fs::File::open(¤t_cuddle_path) {
|
||||
Ok(file) => match serde_yaml::from_reader::<_, T>(file) {
|
||||
Ok(config) => {
|
||||
return Some(config.into());
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::debug!(
|
||||
"{} doesn't contain a valid please config: {}",
|
||||
¤t_cuddle_path.display(),
|
||||
e
|
||||
);
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
tracing::debug!(
|
||||
"did not find or was not allowed to read {}, error: {}",
|
||||
¤t_cuddle_path.display(),
|
||||
e,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
53
crates/cuddle-please-frontend/src/gatheres/execution_env.rs
Normal file
53
crates/cuddle-please-frontend/src/gatheres/execution_env.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use crate::stage0_config::{PleaseConfigBuilder, PleaseProjectConfigBuilder};
|
||||
|
||||
pub fn get_from_environment(vars: std::env::Vars) -> PleaseConfigBuilder {
|
||||
let vars: HashMap<String, String> = vars.collect();
|
||||
|
||||
let env = detect_environment(&vars);
|
||||
|
||||
match env {
|
||||
ExecutionEnvironment::Local => PleaseConfigBuilder {
|
||||
project: Some(PleaseProjectConfigBuilder {
|
||||
source: Some(PathBuf::from(".")),
|
||||
..Default::default()
|
||||
}),
|
||||
settings: None,
|
||||
},
|
||||
ExecutionEnvironment::Drone => PleaseConfigBuilder {
|
||||
project: Some(PleaseProjectConfigBuilder {
|
||||
owner: Some(
|
||||
vars.get("DRONE_REPO_OWNER")
|
||||
.expect("DRONE_REPO_OWNER to be present")
|
||||
.clone(),
|
||||
),
|
||||
repository: Some(
|
||||
vars.get("DRONE_REPO_NAME")
|
||||
.expect("DRONE_REPO_NAME to be present")
|
||||
.clone(),
|
||||
),
|
||||
source: Some(PathBuf::from(".")),
|
||||
branch: Some(
|
||||
vars.get("DRONE_REPO_BRANCH")
|
||||
.expect("DRONE_REPO_BRANCH to be present")
|
||||
.clone(),
|
||||
),
|
||||
}),
|
||||
settings: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn detect_environment(vars: &HashMap<String, String>) -> ExecutionEnvironment {
|
||||
if let Some(_) = vars.get("DRONE".into()) {
|
||||
return ExecutionEnvironment::Drone;
|
||||
}
|
||||
|
||||
ExecutionEnvironment::Local
|
||||
}
|
||||
|
||||
pub enum ExecutionEnvironment {
|
||||
Local,
|
||||
Drone,
|
||||
}
|
9
crates/cuddle-please-frontend/src/gatheres/mod.rs
Normal file
9
crates/cuddle-please-frontend/src/gatheres/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
mod cli;
|
||||
mod config_file;
|
||||
mod execution_env;
|
||||
mod stdin;
|
||||
|
||||
pub use cli::ConfigArgs;
|
||||
pub(crate) use config_file::get_config_from_config_file;
|
||||
pub(crate) use execution_env::get_from_environment;
|
||||
pub(crate) use stdin::get_config_from_stdin;
|
19
crates/cuddle-please-frontend/src/gatheres/stdin.rs
Normal file
19
crates/cuddle-please-frontend/src/gatheres/stdin.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::stage0_config::PleaseConfigBuilder;
|
||||
|
||||
pub fn get_config_from_stdin<'d, T>(stdin: &'d str) -> PleaseConfigBuilder
|
||||
where
|
||||
T: Deserialize<'d>,
|
||||
T: Into<PleaseConfigBuilder>,
|
||||
{
|
||||
match serde_yaml::from_str::<'d, T>(stdin) {
|
||||
Ok(config) => {
|
||||
return config.into();
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::debug!("stdin doesn't contain a valid please config: {}", e);
|
||||
}
|
||||
}
|
||||
PleaseConfigBuilder::default()
|
||||
}
|
Reference in New Issue
Block a user