use breezyshim::error::Error as BrzError;
use breezyshim::tree::Tree;
use std::path::{Path, PathBuf};
include!(concat!(env!("OUT_DIR"), "/generated/mod.rs"));
#[derive(serde::Deserialize, serde::Serialize, Default)]
pub struct ProjectConfig {
#[serde(default)]
pub name: Option<String>,
#[serde(default, rename = "tag-name")]
pub tag_name: Option<String>,
#[serde(default)]
pub update_version: Option<Vec<UpdateVersion>>,
#[serde(default, rename = "update-manpage")]
pub update_manpages: Option<Vec<PathBuf>>,
#[serde(default)]
pub launchpad: Option<Launchpad>,
#[serde(default)]
pub github: Option<GitHub>,
#[serde(default, rename = "news-file")]
pub news_file: Option<PathBuf>,
#[serde(default, rename = "pre-dist-command")]
pub pre_dist_command: Option<String>,
#[serde(default, rename = "verify-command")]
pub verify_command: Option<String>,
#[serde(default, rename = "twine-upload")]
pub twine_upload: Option<bool>,
#[serde(
default,
rename = "tarball-location",
skip_serializing_if = "Vec::is_empty"
)]
pub tarball_location: Vec<String>,
#[serde(default, rename = "release-timeout")]
pub release_timeout: Option<u64>,
#[serde(default, rename = "ci-timeout")]
pub ci_timeout: Option<u64>,
}
#[derive(serde::Deserialize, serde::Serialize)]
pub struct GitHub {
pub url: String,
pub branch: Option<String>,
}
#[derive(serde::Deserialize, serde::Serialize)]
pub struct Launchpad {
pub project: String,
pub series: Option<String>,
}
#[derive(serde::Deserialize, serde::Serialize)]
pub struct UpdateVersion {
pub path: std::path::PathBuf,
pub r#match: Option<String>,
#[serde(rename = "new-line")]
pub new_line: String,
}
impl From<config::UpdateVersion> for UpdateVersion {
fn from(u: config::UpdateVersion) -> Self {
UpdateVersion {
path: u.path.unwrap().into(),
r#match: u.match_,
new_line: u.new_line.unwrap(),
}
}
}
impl From<config::Project> for ProjectConfig {
fn from(p: config::Project) -> Self {
ProjectConfig {
name: p.name,
update_version: {
let vs: Vec<_> = p.update_version.into_iter().map(|u| u.into()).collect();
if vs.is_empty() {
None
} else {
Some(vs)
}
},
launchpad: p.launchpad_project.as_ref().map(|_l| Launchpad {
project: p.launchpad_project.clone().unwrap(),
series: p.launchpad_series.clone(),
}),
github: p.github_url.as_ref().map(|_g| GitHub {
url: p.github_url.clone().unwrap(),
branch: p.github_branch.clone(),
}),
news_file: p.news_file.clone().map(|n| n.into()),
update_manpages: {
let mps: Vec<_> = p.update_manpages.into_iter().map(|u| u.into()).collect();
if mps.is_empty() {
None
} else {
Some(mps)
}
},
tag_name: p.tag_name.clone(),
pre_dist_command: p.pre_dist_command.clone(),
verify_command: p.verify_command.clone(),
twine_upload: p.skip_twine_upload.map(|t| !t),
tarball_location: p.tarball_location.clone(),
release_timeout: p.timeout_days.map(|t| t as u64),
ci_timeout: p.ci_timeout.map(|t| t as u64),
}
}
}
fn read_old_project(f: &mut dyn std::io::Read) -> config::Project {
let mut s = String::new();
std::io::Read::read_to_string(f, &mut s).unwrap();
protobuf::text_format::parse_from_str(&s).unwrap()
}
fn read_toml_project(f: &mut dyn std::io::Read) -> ProjectConfig {
let mut s = String::new();
std::io::Read::read_to_string(f, &mut s).unwrap();
let ret: ProjectConfig = toml::from_str(&s).unwrap();
ret
}
pub fn read_project_with_fallback(tree: &dyn Tree) -> Result<ProjectConfig, BrzError> {
#[allow(unused_assignments)]
let mut first_error = None;
match tree.get_file(Path::new("disperse.toml")) {
Ok(mut f) => return Ok(read_toml_project(&mut f)),
Err(e @ BrzError::NoSuchFile(_)) => {
first_error = Some(e);
}
Err(e) => {
return Err(e);
}
}
let mut old_config = match tree.get_file(Path::new("disperse.conf")) {
Ok(f) => f,
Err(BrzError::NoSuchFile(_)) => match tree.get_file(Path::new("releaser.conf")) {
Err(BrzError::NoSuchFile(_)) => {
return Err(first_error.unwrap());
}
Err(e) => return Err(e),
Ok(f) => f,
},
Err(e) => return Err(e),
};
Ok(read_old_project(&mut old_config).into())
}