mirror of
https://github.com/yuzu-emu/liftinstall.git
synced 2024-11-25 23:55:44 +01:00
Select latest release file in install pipeline
This commit is contained in:
parent
a61709c3d0
commit
139ff5793c
@ -1,5 +1,4 @@
|
||||
/// Serves static files from a asset directory.
|
||||
|
||||
extern crate mime_guess;
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
@ -14,9 +14,8 @@ use sources::get_by_name;
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct PackageSource {
|
||||
pub name: String,
|
||||
#[serde(rename="match")]
|
||||
pub match_regex : String,
|
||||
pub config : toml::Value
|
||||
#[serde(rename = "match")] pub match_regex: String,
|
||||
pub config: toml::Value,
|
||||
}
|
||||
|
||||
/// Describes a overview of a individual package.
|
||||
@ -25,7 +24,7 @@ pub struct PackageDescription {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub default: Option<bool>,
|
||||
pub source: PackageSource
|
||||
pub source: PackageSource,
|
||||
}
|
||||
|
||||
/// Describes the application itself.
|
||||
@ -58,7 +57,7 @@ impl PackageSource {
|
||||
pub fn get_current_releases(&self) -> Result<Vec<Release>, String> {
|
||||
let package_handler = match get_by_name(&self.name) {
|
||||
Some(v) => v,
|
||||
_ => return Err(format!("Handler {} not found", self.name))
|
||||
_ => return Err(format!("Handler {} not found", self.name)),
|
||||
};
|
||||
|
||||
package_handler.get_current_releases(&self.config)
|
||||
|
@ -60,17 +60,21 @@ impl InstallerFramework {
|
||||
|
||||
let results = package.source.get_current_releases().unwrap();
|
||||
|
||||
println!("Got releases");
|
||||
|
||||
let filtered_regex = package.source.match_regex.replace("#PLATFORM#", OS);
|
||||
println!("Filtered regex: {}" , filtered_regex);
|
||||
let regex = Regex::new(&filtered_regex).unwrap();
|
||||
|
||||
// Find the latest release in here
|
||||
let latest_result = results.into_iter()
|
||||
.filter(|f| f.files.iter().filter(|x| regex.is_match(x)).count() > 0)
|
||||
.max_by_key(|f| f.version.clone());
|
||||
println!("{:?}", latest_result);
|
||||
let latest_result = results
|
||||
.into_iter()
|
||||
.filter(|f| f.files.iter().filter(|x| regex.is_match(&x.name)).count() > 0)
|
||||
.max_by_key(|f| f.version.clone()).unwrap();
|
||||
|
||||
// Find the matching file in here
|
||||
let latest_file = latest_result.files.into_iter()
|
||||
.filter(|x| regex.is_match(&x.name))
|
||||
.next().unwrap();
|
||||
|
||||
println!("{:?}", latest_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,8 @@ extern crate serde_derive;
|
||||
extern crate serde_json;
|
||||
extern crate toml;
|
||||
|
||||
extern crate semver;
|
||||
extern crate regex;
|
||||
extern crate semver;
|
||||
|
||||
mod assets;
|
||||
mod rest;
|
||||
|
@ -2,7 +2,6 @@
|
||||
///
|
||||
/// Provides a HTTP/REST server for both frontend<->backend communication, as well
|
||||
/// as talking to external applications.
|
||||
|
||||
extern crate nfd;
|
||||
extern crate url;
|
||||
|
||||
@ -153,7 +152,8 @@ impl Service for WebService {
|
||||
|
||||
return Box::new(req.body().concat2().map(move |b| {
|
||||
let results = form_urlencoded::parse(b.as_ref())
|
||||
.into_owned().collect::<HashMap<String, String>>();
|
||||
.into_owned()
|
||||
.collect::<HashMap<String, String>>();
|
||||
|
||||
let mut to_install = Vec::new();
|
||||
|
||||
@ -194,7 +194,7 @@ impl Service for WebService {
|
||||
.with_header(ContentLength(file.len() as u64))
|
||||
.with_header(content_type)
|
||||
.with_body(file)
|
||||
},
|
||||
}
|
||||
None => Response::new().with_status(StatusCode::NotFound),
|
||||
}
|
||||
}
|
||||
|
@ -18,13 +18,12 @@ use serde_json;
|
||||
|
||||
use sources::types::*;
|
||||
|
||||
pub struct GithubReleases {
|
||||
}
|
||||
pub struct GithubReleases {}
|
||||
|
||||
/// The configuration for this release.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct GithubConfig {
|
||||
repo : String
|
||||
repo: String,
|
||||
}
|
||||
|
||||
impl GithubReleases {
|
||||
@ -38,44 +37,45 @@ impl ReleaseSource for GithubReleases {
|
||||
// Reparse our Config as strongly typed
|
||||
let config_string = match toml::to_string(config) {
|
||||
Ok(v) => v,
|
||||
Err(v) => return Err(format!("Failed to convert config: {:?}", v))
|
||||
Err(v) => return Err(format!("Failed to convert config: {:?}", v)),
|
||||
};
|
||||
|
||||
let config: GithubConfig = match toml::from_str(&config_string) {
|
||||
Ok(v) => v,
|
||||
Err(v) => return Err(format!("Failed to convert config: {:?}", v))
|
||||
Err(v) => return Err(format!("Failed to convert config: {:?}", v)),
|
||||
};
|
||||
|
||||
let mut core = match Core::new() {
|
||||
Ok(v) => v,
|
||||
Err(v) => return Err(format!("Failed to init Tokio: {:?}", v))
|
||||
Err(v) => return Err(format!("Failed to init Tokio: {:?}", v)),
|
||||
};
|
||||
|
||||
// Build the HTTP client up
|
||||
let client = Client::configure()
|
||||
.connector(match HttpsConnector::new(4, &core.handle()) {
|
||||
Ok(v) => v,
|
||||
Err(v) => return Err(format!("Failed to init https: {:?}", v))
|
||||
Err(v) => return Err(format!("Failed to init https: {:?}", v)),
|
||||
})
|
||||
.build(&core.handle());
|
||||
|
||||
let mut results: Vec<Release> = Vec::new();
|
||||
let target_url : Uri = match format!("https://api.github.com/repos/{}/releases",
|
||||
config.repo).parse() {
|
||||
let target_url: Uri =
|
||||
match format!("https://api.github.com/repos/{}/releases", config.repo).parse() {
|
||||
Ok(v) => v,
|
||||
Err(v) => return Err(format!("Failed to generate target url: {:?}", v))
|
||||
Err(v) => return Err(format!("Failed to generate target url: {:?}", v)),
|
||||
};
|
||||
|
||||
let mut req = Request::new(Method::Get, target_url);
|
||||
req.headers_mut().set(UserAgent::new("installer-rs (j-selby)"));
|
||||
req.headers_mut()
|
||||
.set(UserAgent::new("installer-rs (j-selby)"));
|
||||
|
||||
// Build our future
|
||||
let future = client.request(req).and_then(|res| {
|
||||
res.body().concat2().and_then(move |body| {
|
||||
let raw_json : Result<serde_json::Value, String>
|
||||
= match serde_json::from_slice(&body) {
|
||||
let raw_json: Result<serde_json::Value, String> =
|
||||
match serde_json::from_slice(&body) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(v) => Err(format!("Failed to parse response: {:?}", v))
|
||||
Err(v) => Err(format!("Failed to parse response: {:?}", v)),
|
||||
};
|
||||
|
||||
Ok(raw_json)
|
||||
@ -85,12 +85,12 @@ impl ReleaseSource for GithubReleases {
|
||||
// Unwrap the future's results
|
||||
let result: serde_json::Value = match core.run(future) {
|
||||
Ok(v) => v,
|
||||
Err(v) => return Err(format!("Failed to fetch info: {:?}", v))
|
||||
Err(v) => return Err(format!("Failed to fetch info: {:?}", v)),
|
||||
}?;
|
||||
|
||||
let result: &Vec<serde_json::Value> = match result.as_array() {
|
||||
Some(v) => v,
|
||||
None => return Err(format!("JSON payload not an array"))
|
||||
None => return Err(format!("JSON payload not an array")),
|
||||
};
|
||||
|
||||
// Parse JSON from server
|
||||
@ -99,26 +99,42 @@ impl ReleaseSource for GithubReleases {
|
||||
|
||||
let id: u64 = match entry["id"].as_u64() {
|
||||
Some(v) => v,
|
||||
None => return Err(format!("JSON payload missing information about ID"))
|
||||
None => return Err(format!("JSON payload missing information about ID")),
|
||||
};
|
||||
|
||||
let assets = match entry["assets"].as_array() {
|
||||
Some(v) => v,
|
||||
None => return Err(format!("JSON payload not an array"))
|
||||
None => return Err(format!("JSON payload not an array")),
|
||||
};
|
||||
|
||||
for asset in assets.into_iter() {
|
||||
let string = match asset["name"].as_str() {
|
||||
Some(v) => v,
|
||||
None => return Err(format!("JSON payload missing information about ID"))
|
||||
None => {
|
||||
return Err(format!(
|
||||
"JSON payload missing information about release name"
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
files.push(string.to_owned());
|
||||
let url = match asset["browser_download_url"].as_str() {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
return Err(format!(
|
||||
"JSON payload missing information about release URL"
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
files.push(File {
|
||||
name: string.to_owned(),
|
||||
url: url.to_owned(),
|
||||
});
|
||||
}
|
||||
|
||||
results.push(Release {
|
||||
version: Version::new_number(id),
|
||||
files
|
||||
files,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -11,9 +11,7 @@ use self::types::ReleaseSource;
|
||||
/// Returns a ReleaseSource by a name, if possible
|
||||
pub fn get_by_name(name: &str) -> Option<Box<ReleaseSource>> {
|
||||
match name {
|
||||
"github" => {
|
||||
Some(Box::new(github::GithubReleases::new()))
|
||||
}
|
||||
_ => None
|
||||
"github" => Some(Box::new(github::GithubReleases::new())),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ pub use toml::value::Value as TomlValue;
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub enum Version {
|
||||
Semver(SemverVersion),
|
||||
Integer(u64)
|
||||
Integer(u64),
|
||||
}
|
||||
|
||||
impl Version {
|
||||
@ -21,8 +21,9 @@ impl Version {
|
||||
fn coarse_into_semver(&self) -> SemverVersion {
|
||||
match self {
|
||||
&Version::Semver(ref version) => version.to_owned(),
|
||||
&Version::Integer(ref version) => SemverVersion::from((version.to_owned(),
|
||||
0 as u64, 0 as u64))
|
||||
&Version::Integer(ref version) => {
|
||||
SemverVersion::from((version.to_owned(), 0 as u64, 0 as u64))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,18 +41,14 @@ impl Version {
|
||||
impl PartialOrd for Version {
|
||||
fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
|
||||
match self {
|
||||
&Version::Semver(ref version) => {
|
||||
match other {
|
||||
&Version::Semver(ref version) => match other {
|
||||
&Version::Semver(ref other_version) => Some(version.cmp(other_version)),
|
||||
_ => None
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
&Version::Integer(ref num) => {
|
||||
match other {
|
||||
&Version::Integer(ref num) => match other {
|
||||
&Version::Integer(ref other_num) => Some(num.cmp(other_num)),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -62,11 +59,18 @@ impl Ord for Version {
|
||||
}
|
||||
}
|
||||
|
||||
/// A individual file in a release.
|
||||
#[derive(Debug)]
|
||||
pub struct File {
|
||||
pub name: String,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
/// A individual release of an application.
|
||||
#[derive(Debug)]
|
||||
pub struct Release {
|
||||
pub version: Version,
|
||||
pub files : Vec<String>
|
||||
pub files: Vec<File>,
|
||||
}
|
||||
|
||||
/// A source of releases.
|
||||
|
Loading…
Reference in New Issue
Block a user