codegen: Minor cleanup

This commit is contained in:
Taiki Endo
2022-12-26 22:51:52 +09:00
parent 4a0357e67d
commit c7fca72a9a

View File

@@ -1,4 +1,4 @@
use anyhow::{Context as _, Result}; use anyhow::{bail, Context as _, Result};
use fs_err as fs; use fs_err as fs;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
@@ -10,6 +10,7 @@ use std::{
path::Path, path::Path,
slice, slice,
str::FromStr, str::FromStr,
time::Duration,
}; };
fn main() -> Result<()> { fn main() -> Result<()> {
@@ -37,6 +38,7 @@ fn main() -> Result<()> {
.repository .repository
.strip_prefix("https://github.com/") .strip_prefix("https://github.com/")
.context("repository must be starts with https://github.com/")?; .context("repository must be starts with https://github.com/")?;
eprintln!("downloading releases of https://github.com/{repo}"); eprintln!("downloading releases of https://github.com/{repo}");
let mut releases: github::Releases = vec![]; let mut releases: github::Releases = vec![];
for page in 1.. { for page in 1.. {
@@ -61,7 +63,7 @@ fn main() -> Result<()> {
}) })
.collect(); .collect();
let mut manifests: Manifests = BTreeMap::new(); let mut manifests: Manifests = Manifests::default();
let mut semver_versions = BTreeSet::new(); let mut semver_versions = BTreeSet::new();
let mut has_build_metadata = false; let mut has_build_metadata = false;
@@ -79,8 +81,8 @@ fn main() -> Result<()> {
} }
let version_req: Option<semver::VersionReq> = match args.get(1) { let version_req: Option<semver::VersionReq> = match args.get(1) {
_ if latest_only => { _ if latest_only => {
if !manifests.is_empty() if !manifests.map.is_empty()
&& manifests.first_key_value().unwrap().1.version && manifests.map.first_key_value().unwrap().1.version
== releases.first().unwrap().0.parse()? == releases.first().unwrap().0.parse()?
{ {
return Ok(()); return Ok(());
@@ -92,7 +94,7 @@ fn main() -> Result<()> {
None => Some(">= 0.0.1".parse()?), // HACK: ignore pre-releases None => Some(">= 0.0.1".parse()?), // HACK: ignore pre-releases
}, },
Some(version_req) => { Some(version_req) => {
for version in manifests.keys() { for version in manifests.map.keys() {
let Some(semver_version) = version.0.to_semver() else { let Some(semver_version) = version.0.to_semver() else {
continue; continue;
}; };
@@ -103,7 +105,7 @@ fn main() -> Result<()> {
} }
let req = if version_req == "latest" { let req = if version_req == "latest" {
if manifests.is_empty() { if manifests.map.is_empty() {
format!("={}", releases.first().unwrap().0).parse()? format!("={}", releases.first().unwrap().0).parse()?
} else { } else {
format!(">{}", semver_versions.last().unwrap()).parse()? format!(">{}", semver_versions.last().unwrap()).parse()?
@@ -142,7 +144,7 @@ fn main() -> Result<()> {
.as_slice() .as_slice()
.iter() .iter()
.map(|asset_name| replace_vars(asset_name, package, version, platform)) .map(|asset_name| replace_vars(asset_name, package, version, platform))
.collect::<Vec<_>>(); .collect::<Result<Vec<_>>>()?;
let (url, asset_name) = match asset_names.iter().find_map(|asset_name| { let (url, asset_name) = match asset_names.iter().find_map(|asset_name| {
release release
.assets .assets
@@ -191,7 +193,8 @@ fn main() -> Result<()> {
.bin .bin
.as_ref() .as_ref()
.or(base_info.bin.as_ref()) .or(base_info.bin.as_ref())
.map(|s| replace_vars(s, package, version, platform)), .map(|s| replace_vars(s, package, version, platform))
.transpose()?,
}, },
); );
buf.clear(); buf.clear();
@@ -217,7 +220,7 @@ fn main() -> Result<()> {
if semver_version.pre.is_empty() { if semver_version.pre.is_empty() {
semver_versions.insert(semver_version.clone()); semver_versions.insert(semver_version.clone());
} }
manifests.insert( manifests.map.insert(
Reverse(semver_version.clone().into()), Reverse(semver_version.clone().into()),
Manifest { Manifest {
version: semver_version.into(), version: semver_version.into(),
@@ -233,27 +236,27 @@ fn main() -> Result<()> {
let mut prev_version = semver_versions.iter().next().unwrap(); let mut prev_version = semver_versions.iter().next().unwrap();
for version in &semver_versions { for version in &semver_versions {
if !(version.major == 0 && version.minor == 0) { if !(version.major == 0 && version.minor == 0) {
manifests.insert( manifests.map.insert(
Reverse(Version::new(version.major, Some(version.minor))), Reverse(Version::new(version.major, Some(version.minor))),
manifests[&Reverse(Version::from(version.clone()))].clone(), manifests.map[&Reverse(Version::from(version.clone()))].clone(),
); );
} }
if version.major != 0 { if version.major != 0 {
manifests.insert( manifests.map.insert(
Reverse(Version::new(version.major, None)), Reverse(Version::new(version.major, None)),
manifests[&Reverse(Version::from(version.clone()))].clone(), manifests.map[&Reverse(Version::from(version.clone()))].clone(),
); );
} }
prev_version = version; prev_version = version;
} }
manifests.insert( manifests.map.insert(
Reverse(Version::latest()), Reverse(Version::latest()),
manifests[&Reverse(Version::from(prev_version.clone()))].clone(), manifests.map[&Reverse(Version::from(prev_version.clone()))].clone(),
); );
} }
if latest_only { if latest_only {
manifests.retain(|k, _| k.0 == Version::latest()); manifests.map.retain(|k, _| k.0 == Version::latest());
} }
let mut buf = serde_json::to_vec_pretty(&manifests)?; let mut buf = serde_json::to_vec_pretty(&manifests)?;
@@ -263,12 +266,17 @@ fn main() -> Result<()> {
Ok(()) Ok(())
} }
fn replace_vars(s: &str, package: &str, version: &str, platform: HostPlatform) -> String { fn replace_vars(s: &str, package: &str, version: &str, platform: HostPlatform) -> Result<String> {
s.replace("${package}", package) let s = s
.replace("${package}", package)
.replace("${tool}", package) .replace("${tool}", package)
.replace("${rust_target}", platform.rust_target()) .replace("${rust_target}", platform.rust_target())
.replace("${version}", version) .replace("${version}", version)
.replace("${exe}", platform.exe_suffix()) .replace("${exe}", platform.exe_suffix());
if s.contains('$') {
bail!("variable not fully replaced: '{s}'");
}
Ok(s)
} }
fn download(url: &str) -> Result<ureq::Response> { fn download(url: &str) -> Result<ureq::Response> {
@@ -286,13 +294,11 @@ fn download(url: &str) -> Result<ureq::Response> {
} }
retry += 1; retry += 1;
eprintln!("download failed; retrying ({retry}/5)"); eprintln!("download failed; retrying ({retry}/5)");
std::thread::sleep(std::time::Duration::from_secs(1)); std::thread::sleep(Duration::from_secs(1));
} }
Err(last_error.unwrap().into()) Err(last_error.unwrap().into())
} }
type Manifests = BTreeMap<Reverse<Version>, Manifest>;
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
struct Version { struct Version {
major: Option<u64>, major: Option<u64>,
@@ -363,19 +369,18 @@ impl Ord for Version {
} }
impl fmt::Display for Version { impl fmt::Display for Version {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
'scope: {
let Some(major) = self.major else { let Some(major) = self.major else {
f.write_str("latest")?; f.write_str("latest")?;
break 'scope; return Ok(());
}; };
f.write_str(&major.to_string())?; f.write_str(&major.to_string())?;
let Some(minor) = self.minor else { let Some(minor) = self.minor else {
break 'scope; return Ok(());
}; };
f.write_str(".")?; f.write_str(".")?;
f.write_str(&minor.to_string())?; f.write_str(&minor.to_string())?;
let Some(patch) = self.patch else { let Some(patch) = self.patch else {
break 'scope; return Ok(());
}; };
f.write_str(".")?; f.write_str(".")?;
f.write_str(&patch.to_string())?; f.write_str(&patch.to_string())?;
@@ -387,7 +392,6 @@ impl fmt::Display for Version {
f.write_str("+")?; f.write_str("+")?;
f.write_str(&self.build)?; f.write_str(&self.build)?;
} }
}
Ok(()) Ok(())
} }
} }
@@ -432,6 +436,12 @@ impl<'de> Deserialize<'de> for Version {
} }
} }
#[derive(Debug, Default, Serialize, Deserialize)]
struct Manifests {
#[serde(flatten)]
map: BTreeMap<Reverse<Version>, Manifest>,
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
struct Manifest { struct Manifest {
// TODO: only serialize version if key != version? // TODO: only serialize version if key != version?