Refactor(Updater) Modernize Updater Crate and add Utils Crate (#335)

* update updater

* basic utils refactor.

* fix platform file.

* add errors.

* fix cargo.toml

* Rename cargo.toml to Cargo.toml

* remove warning.
This commit is contained in:
Tensor-Programming 2020-01-17 19:33:17 -05:00 committed by GitHub
parent b9f3d9a92c
commit 91bf26c336
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 196 additions and 421 deletions

View File

@ -3,4 +3,5 @@ members = [
"tauri",
"tauri-api",
"tauri-updater",
"tauri-utils"
]

View File

@ -33,6 +33,8 @@ toml = "0.5.5"
uuid = { version = "0.8", features = ["v5"] }
walkdir = "2"
tauri-utils = {version = "0.3", path = "../../tauri-utils"}
[target.'cfg(target_os = "windows")'.dependencies]
attohttpc = { version = "0.10.1" }
regex = { version = "1" }

View File

@ -1,6 +1,5 @@
use super::category::AppCategory;
use crate::bundle::common;
use crate::platform::target_triple;
use clap::ArgMatches;
use glob;
@ -10,6 +9,7 @@ use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
use target_build_utils::TargetInfo;
use tauri_utils::platform::target_triple;
use toml;
use walkdir;

View File

@ -11,7 +11,6 @@ extern crate serde_derive;
extern crate tempfile;
mod bundle;
mod platform;
use crate::bundle::{bundle_project, check_icons, BuildArtifact, PackageType, Settings};
use clap::{App, AppSettings, Arg, SubCommand};
@ -30,6 +29,7 @@ error_chain! {
Walkdir(::walkdir::Error);
StripError(std::path::StripPrefixError);
ConvertError(std::num::TryFromIntError);
PlatformError(::tauri_utils::Error);
RegexError(::regex::Error) #[cfg(windows)];
HttpError(::attohttpc::Error) #[cfg(windows)];
}

View File

@ -22,6 +22,9 @@ tar = "0.4"
flate2 = "1"
error-chain = "0.12"
tauri-utils = {version = "0.3.0", path = "../tauri-utils"}
[dev-dependencies]
quickcheck = "0.9.2"
quickcheck_macros = "0.9.1"

View File

@ -1,6 +1,6 @@
use std::process::{Child, Command, Stdio};
use crate::platform;
use tauri_utils::platform;
pub fn get_output(cmd: String, args: Vec<String>, stdout: Stdio) -> crate::Result<String> {
Command::new(cmd)

View File

@ -12,7 +12,6 @@ extern crate quickcheck_macros;
pub mod command;
pub mod dir;
pub mod file;
pub mod platform;
pub mod rpc;
pub mod version;
@ -22,7 +21,8 @@ error_chain! {
foreign_links {
Io(::std::io::Error);
ZipError(::zip::result::ZipError);
SemVer(semver::SemVerError);
SemVer(::semver::SemVerError);
Platform(::tauri_utils::Error);
}
errors {
Extract(t: String) {

View File

@ -1,51 +0,0 @@
/// Try to determine the current target triple.
///
/// Returns a target triple (e.g. `x86_64-unknown-linux-gnu` or `i686-pc-windows-msvc`) or an
/// `Error::Config` if the current config cannot be determined or is not some combination of the
/// following values:
/// `linux, mac, windows` -- `i686, x86, armv7` -- `gnu, musl, msvc`
///
/// * Errors:
/// * Unexpected system config
pub fn target_triple() -> Result<String, String> {
let arch = if cfg!(target_arch = "x86") {
"i686"
} else if cfg!(target_arch = "x86_64") {
"x86_64"
} else if cfg!(target_arch = "arm") {
"armv7"
} else {
return Err("Unable to determine target-architecture".to_string());
};
let os = if cfg!(target_os = "linux") {
"unknown-linux"
} else if cfg!(target_os = "macos") {
"apple-darwin"
} else if cfg!(target_os = "windows") {
"pc-windows"
} else if cfg!(target_os = "freebsd") {
"unknown-freebsd"
} else {
return Err("Unable to determine target-os".to_string());
};
let s;
let os = if cfg!(target_os = "macos") || cfg!(target_os = "freebsd") {
os
} else {
let env = if cfg!(target_env = "gnu") {
"gnu"
} else if cfg!(target_env = "musl") {
"musl"
} else if cfg!(target_env = "msvc") {
"msvc"
} else {
return Err("Unable to determine target-environment".to_string());
};
s = format!("{}-{}", os, env);
&s
};
Ok(format!("{}-{}", arch, os))
}

View File

@ -10,13 +10,12 @@ edition = "2018"
exclude = ["test/fixture/**"]
[dependencies]
reqwest = "0.9"
hyper-old-types = "0.11.0"
pbr = "1"
attohttpc = {version = "0.10.1", features=["json", "compress" ]}
# pbr = "1"
serde_json = "1.0.44"
serde = "1.0"
zip = "0.5.3"
sysinfo = "0.10"
tempdir = "0.3"
error-chain = "0.12.1"
tauri-api = { version = "0.3", path = "../tauri-api" }
tauri-utils = { version = "0.3", path = "../tauri-utils" }

View File

@ -1,80 +1,36 @@
use pbr;
use reqwest;
use attohttpc;
use serde::Serialize;
use std::io;
mod error;
pub use self::error::Error;
pub fn get(url: &String) -> Result<reqwest::Response, Error> {
let response = reqwest::Client::new().get(url).send()?;
use std::io::{BufWriter, Write};
pub(crate) mod link_value;
pub fn get(url: &String) -> crate::Result<attohttpc::Response> {
let response = attohttpc::get(url).send()?;
Ok(response)
}
pub fn post_as_json<T: Serialize + ?Sized>(
url: &String,
payload: &T,
) -> Result<reqwest::Response, Error> {
let response = reqwest::Client::new().post(url).json(payload).send()?;
pub fn post_as_json<T: Serialize>(url: &String, payload: &T) -> crate::Result<attohttpc::Response> {
let response = attohttpc::post(url).json(payload)?.send()?;
Ok(response)
}
pub fn download<T: io::Write>(
url: &String,
mut dest: T,
display_progress: bool,
) -> Result<(), Error> {
use io::BufRead;
pub fn download<T: Write>(url: &String, dest: T, _display_progress: bool) -> crate::Result<()> {
set_ssl_vars!();
let resp = get(url)?;
let size = resp
.headers()
.get(reqwest::header::CONTENT_LENGTH)
.map(|val| {
val
.to_str()
.map(|s| s.parse::<u64>().unwrap_or(0))
.unwrap_or(0)
})
.unwrap_or(0);
if !resp.status().is_success() {
bail!(
Error::Download,
crate::ErrorKind::Download,
"Download request failed with status: {:?}",
resp.status()
)
}
let show_progress = if size == 0 { false } else { display_progress };
let mut src = io::BufReader::new(resp);
let mut bar = if show_progress {
let mut bar = pbr::ProgressBar::new(size);
bar.set_units(pbr::Units::Bytes);
bar.format("[=> ]");
Some(bar)
} else {
None
};
loop {
let n = {
let buf = src.fill_buf()?;
dest.write_all(&buf)?;
buf.len()
};
if n == 0 {
break;
}
src.consume(n);
if let Some(ref mut bar) = bar {
bar.add(n as u64);
}
}
if show_progress {
println!(" ... Done");
}
let file = BufWriter::new(dest);
resp.write_to(file)?;
Ok(())
}

View File

@ -1,57 +0,0 @@
use reqwest;
use serde_json;
use std;
#[derive(Debug)]
pub enum Error {
Download(String),
Json(serde_json::Error),
Reqwest(reqwest::Error),
Io(std::io::Error),
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use Error::*;
match *self {
Download(ref s) => write!(f, "DownloadError: {}", s),
Json(ref e) => write!(f, "JsonError: {}", e),
Reqwest(ref e) => write!(f, "ReqwestError: {}", e),
Io(ref e) => write!(f, "IoError: {}", e),
}
}
}
impl std::error::Error for Error {
fn description(&self) -> &str {
"Http Error"
}
fn cause(&self) -> Option<&dyn std::error::Error> {
use Error::*;
Some(match *self {
Json(ref e) => e,
Reqwest(ref e) => e,
Io(ref e) => e,
_ => return None,
})
}
}
impl From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Self {
Error::Json(e)
}
}
impl From<reqwest::Error> for Error {
fn from(e: reqwest::Error) -> Self {
Error::Reqwest(e)
}
}
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Self {
Error::Io(e)
}
}

View File

@ -0,0 +1,35 @@
use std::borrow::Cow;
#[derive(Clone, PartialEq, Debug)]
pub struct LinkValue {
/// Target IRI: `link-value`.
link: Cow<'static, str>,
/// Forward Relation Types: `rel`.
rel: Option<Vec<RelationType>>,
}
impl LinkValue {
pub fn new<T>(uri: T) -> LinkValue
where
T: Into<Cow<'static, str>>,
{
LinkValue {
link: uri.into(),
rel: None,
}
}
pub fn rel(&self) -> Option<&[RelationType]> {
self.rel.as_ref().map(AsRef::as_ref)
}
}
#[derive(Clone, PartialEq, Debug)]
pub enum RelationType {
/// next.
Next,
/// ext-rel-type.
#[allow(dead_code)]
ExtRelType(String),
}

View File

@ -2,6 +2,38 @@
pub mod macros;
pub mod http;
pub mod platform;
pub mod process;
pub mod updater;
use error_chain::error_chain;
error_chain! {
foreign_links{
Io(::std::io::Error);
Json(::serde_json::Error);
Zip(::zip::result::ZipError);
API(::tauri_api::Error);
HTTP(::attohttpc::Error);
}
errors{
Download(t: String) {
description("Download Error")
display("Download Error: '{}'", t)
}
Updater(t: String) {
description("Updater Error")
display("Updater Error: '{}'", t)
}
Release(t: String) {
description("Release Error")
display("Release Error: '{}'", t)
}
Network(t: String) {
description("Network Error")
display("Network Error: '{}'", t)
}
Config(t: String) {
description("Config Error")
display("Config Error: '{}'", t)
}
}
}

View File

@ -1,33 +1,32 @@
/// Helper for formatting `errors::Error`s
macro_rules! format_err {
($e_type:expr, $literal:expr) => {
$e_type(format!($literal))
};
($e_type:expr, $literal:expr, $($arg:expr),*) => {
$e_type(format!($literal, $($arg),*))
};
($e_type:expr, $literal:expr) => {
$e_type(format!($literal))
};
($e_type:expr, $literal:expr, $($arg:expr),*) => {
$e_type(format!($literal, $($arg),*))
};
}
/// Helper for formatting `errors::Error`s and returning early
macro_rules! bail {
($e_type:expr, $literal:expr) => {
return Err(format_err!($e_type, $literal))
};
($e_type:expr, $literal:expr, $($arg:expr),*) => {
return Err(format_err!($e_type, $literal, $($arg),*))
};
($e_type:expr, $literal:expr) => {
return Err(format_err!($e_type, $literal).into())
};
($e_type:expr, $literal:expr, $($arg:expr),*) => {
return Err(format_err!($e_type, $literal, $($arg),*).into())
};
}
/// Helper to `print!` and immediately `flush` `stdout`
macro_rules! print_flush {
($literal:expr) => {
print!($literal);
::std::io::Write::flush(&mut ::std::io::stdout())?;
};
($literal:expr, $($arg:expr),*) => {
print!($literal, $($arg),*);
::std::io::Write::flush(&mut ::std::io::stdout())?;
}
($literal:expr) => {
print!($literal);
::std::io::Write::flush(&mut ::std::io::stdout())?;
};
($literal:expr, $($arg:expr),*) => {
print!($literal, $($arg),*);
::std::io::Write::flush(&mut ::std::io::stdout())?;
}
}
/// Set ssl cert env. vars to make sure openssl can find required files

View File

@ -1,54 +0,0 @@
pub mod error;
use error::*;
/// Try to determine the current target triple.
///
/// Returns a target triple (e.g. `x86_64-unknown-linux-gnu` or `i686-pc-windows-msvc`) or an
/// `Error::Config` if the current config cannot be determined or is not some combination of the
/// following values:
/// `linux, mac, windows` -- `i686, x86, armv7` -- `gnu, musl, msvc`
///
/// * Errors:
/// * Unexpected system config
pub fn target_triple() -> Result<String, Error> {
let arch = if cfg!(target_arch = "x86") {
"i686"
} else if cfg!(target_arch = "x86_64") {
"x86_64"
} else if cfg!(target_arch = "arm") {
"armv7"
} else {
bail!(Error::Arch, "Unable to determine target-architecture")
};
let os = if cfg!(target_os = "linux") {
"unknown-linux"
} else if cfg!(target_os = "macos") {
"apple-darwin"
} else if cfg!(target_os = "windows") {
"pc-windows"
} else if cfg!(target_os = "freebsd") {
"unknown-freebsd"
} else {
bail!(Error::Target, "Unable to determine target-os");
};
let s;
let os = if cfg!(target_os = "macos") || cfg!(target_os = "freebsd") {
os
} else {
let env = if cfg!(target_env = "gnu") {
"gnu"
} else if cfg!(target_env = "musl") {
"musl"
} else if cfg!(target_env = "msvc") {
"msvc"
} else {
bail!(Error::Abi, "Unable to determine target-environment")
};
s = format!("{}-{}", os, env);
&s
};
Ok(format!("{}-{}", arch, os))
}

View File

@ -1,29 +0,0 @@
use std;
#[derive(Debug)]
pub enum Error {
Arch(String),
Target(String),
Abi(String),
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use Error::*;
match *self {
Arch(ref s) => write!(f, "ArchError: {}", s),
Target(ref e) => write!(f, "TargetError: {}", e),
Abi(ref e) => write!(f, "AbiError: {}", e),
}
}
}
impl std::error::Error for Error {
fn description(&self) -> &str {
"Platform Error"
}
fn cause(&self) -> Option<&dyn std::error::Error> {
return None;
}
}

View File

@ -7,9 +7,6 @@ use tauri_api::file::{Extract, Move};
pub mod github;
mod error;
pub use error::Error;
/// Status returned after updating
///
/// Wrapped `String`s are version tags
@ -68,7 +65,7 @@ impl UpdateBuilder {
///
/// * Errors:
/// * Io - Determining current exe path
pub fn new() -> Result<Self, Error> {
pub fn new() -> crate::Result<UpdateBuilder> {
Ok(Self {
release: None,
bin_name: None,
@ -157,32 +154,32 @@ impl UpdateBuilder {
///
/// * Errors:
/// * Config - Invalid `Update` configuration
pub fn build(&self) -> Result<Update, Error> {
pub fn build(&self) -> crate::Result<Update> {
Ok(Update {
release: if let Some(ref release) = self.release {
release.to_owned()
} else {
bail!(Error::Config, "`release` required")
bail!(crate::ErrorKind::Config, "`release` required")
},
bin_name: if let Some(ref name) = self.bin_name {
name.to_owned()
} else {
bail!(Error::Config, "`bin_name` required")
bail!(crate::ErrorKind::Config, "`bin_name` required")
},
bin_install_path: if let Some(ref path) = self.bin_install_path {
path.to_owned()
} else {
bail!(Error::Config, "`bin_install_path` required")
bail!(crate::ErrorKind::Config, "`bin_install_path` required")
},
bin_path_in_archive: if let Some(ref path) = self.bin_path_in_archive {
path.to_owned()
} else {
bail!(Error::Config, "`bin_path_in_archive` required")
bail!(crate::ErrorKind::Config, "`bin_path_in_archive` required")
},
current_version: if let Some(ref ver) = self.current_version {
ver.to_owned()
} else {
bail!(Error::Config, "`current_version` required")
bail!(crate::ErrorKind::Config, "`current_version` required")
},
show_download_progress: self.show_download_progress,
show_output: self.show_output,
@ -203,11 +200,11 @@ pub struct Update {
}
impl Update {
/// Initialize a new `Update` builder
pub fn configure() -> Result<UpdateBuilder, Error> {
pub fn configure() -> crate::Result<UpdateBuilder> {
UpdateBuilder::new()
}
fn print_flush(&self, msg: &str) -> Result<(), Error> {
fn print_flush(&self, msg: &str) -> crate::Result<()> {
if self.show_output {
print_flush!("{}", msg);
}
@ -220,7 +217,7 @@ impl Update {
}
}
pub fn update(self) -> Result<Status, Error> {
pub fn update(self) -> crate::Result<Status> {
self.println(&format!(
"Checking current version... v{}",
self.current_version
@ -238,7 +235,7 @@ impl Update {
let tmp_dir_parent = self
.bin_install_path
.parent()
.ok_or_else(|| Error::Updater("Failed to determine parent dir".into()))?;
.ok_or_else(|| crate::ErrorKind::Updater("Failed to determine parent dir".into()))?;
let tmp_dir =
tempdir::TempDir::new_in(&tmp_dir_parent, &format!("{}_download", self.bin_name))?;
let tmp_archive_path = tmp_dir.path().join(&self.release.asset_name);

View File

@ -1,87 +0,0 @@
use crate::http;
use reqwest;
use std;
use tauri_api;
// use tauri_api::file;
// use tauri_api::version;
use zip::result::ZipError;
#[derive(Debug)]
pub enum Error {
Updater(String),
Release(String),
Network(String),
Config(String),
Io(std::io::Error),
Zip(ZipError),
API(tauri_api::Error),
// File(file::Error),
// Version(version::Error),
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use Error::*;
match *self {
Updater(ref s) => write!(f, "UpdaterError: {}", s),
Release(ref s) => write!(f, "ReleaseError: {}", s),
Network(ref s) => write!(f, "NetworkError: {}", s),
Config(ref s) => write!(f, "ConfigError: {}", s),
Io(ref e) => write!(f, "IoError: {}", e),
Zip(ref e) => write!(f, "ZipError: {}", e),
API(ref e) => write!(f, "APIError: {}", e),
// File(ref e) => write!(f, "FileError: {}", e),
// Version(ref e) => write!(f, "VersionError: {}", e),
}
}
}
impl std::error::Error for Error {
fn description(&self) -> &str {
"Updater Error"
}
fn cause(&self) -> Option<&dyn std::error::Error> {
use Error::*;
Some(match *self {
Io(ref e) => e,
_ => return None,
})
}
}
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Self {
Error::Io(e)
}
}
// impl From<file::Error> for Error {
// fn from(e: file::Error) -> Self {
// Error::File(e)
// }
// }
impl From<http::Error> for Error {
fn from(e: http::Error) -> Self {
Error::Network(e.to_string())
}
}
impl From<reqwest::Error> for Error {
fn from(e: reqwest::Error) -> Self {
Error::Network(e.to_string())
}
}
impl From<tauri_api::Error> for Error {
fn from(e: tauri_api::Error) -> Self {
Error::API(e)
}
}
// impl From<version::Error> for Error {
// fn from(e: version::Error) -> Self {
// Error::Version(e)
// }
// }

View File

@ -1,19 +1,19 @@
mod release;
pub use crate::updater::error::Error;
pub use release::*;
use crate::http;
pub fn get_latest_release(repo_owner: &str, repo_name: &str) -> Result<Release, Error> {
pub fn get_latest_release(repo_owner: &str, repo_name: &str) -> crate::Result<Release> {
set_ssl_vars!();
let api_url = format!(
"https://api.github.com/repos/{}/{}/releases/latest",
repo_owner, repo_name
);
let mut resp = http::get(&api_url)?;
let resp = http::get(&api_url)?;
if !resp.status().is_success() {
bail!(
Error::Network,
crate::ErrorKind::Network,
"api request failed with status: {:?} - for: {:?}",
resp.status(),
api_url
@ -23,16 +23,16 @@ pub fn get_latest_release(repo_owner: &str, repo_name: &str) -> Result<Release,
Ok(Release::parse(&json)?)
}
pub fn get_release_version(repo_owner: &str, repo_name: &str, ver: &str) -> Result<Release, Error> {
pub fn get_release_version(repo_owner: &str, repo_name: &str, ver: &str) -> crate::Result<Release> {
set_ssl_vars!();
let api_url = format!(
"https://api.github.com/repos/{}/{}/releases/tags/{}",
repo_owner, repo_name, ver
);
let mut resp = http::get(&api_url)?;
let resp = http::get(&api_url)?;
if !resp.status().is_success() {
bail!(
Error::Network,
crate::ErrorKind::Network,
"api request failed with status: {:?} - for: {:?}",
resp.status(),
api_url

View File

@ -1,5 +1,5 @@
use crate::updater::error::*;
use hyper_old_types::header::{LinkValue, RelationType};
use crate::http::link_value::{LinkValue, RelationType};
use serde_json;
/// GitHub release-asset information
@ -13,13 +13,16 @@ impl ReleaseAsset {
///
/// Errors:
/// * Missing required name & browser_download_url keys
fn from_asset(asset: &serde_json::Value) -> Result<ReleaseAsset, Error> {
let download_url = asset["browser_download_url"]
.as_str()
.ok_or_else(|| format_err!(Error::Release, "Asset missing `browser_download_url`"))?;
fn from_asset(asset: &serde_json::Value) -> crate::Result<ReleaseAsset> {
let download_url = asset["browser_download_url"].as_str().ok_or_else(|| {
format_err!(
crate::ErrorKind::Network,
"Asset missing `browser_download_url`"
)
})?;
let name = asset["name"]
.as_str()
.ok_or_else(|| format_err!(Error::Release, "Asset missing `name`"))?;
.ok_or_else(|| format_err!(crate::ErrorKind::Network, "Asset missing `name`"))?;
Ok(ReleaseAsset {
download_url: download_url.to_owned(),
name: name.to_owned(),
@ -36,22 +39,22 @@ pub struct Release {
pub assets: Vec<ReleaseAsset>,
}
impl Release {
pub fn parse(release: &serde_json::Value) -> Result<Release, Error> {
pub fn parse(release: &serde_json::Value) -> crate::Result<Release> {
let tag = release["tag_name"]
.as_str()
.ok_or_else(|| format_err!(Error::Release, "Release missing `tag_name`"))?;
.ok_or_else(|| format_err!(crate::ErrorKind::Network, "Release missing `tag_name`"))?;
let date_created = release["created_at"]
.as_str()
.ok_or_else(|| format_err!(Error::Release, "Release missing `created_at`"))?;
.ok_or_else(|| format_err!(crate::ErrorKind::Network, "Release missing `created_at`"))?;
let name = release["name"].as_str().unwrap_or(tag);
let body = release["body"].as_str().unwrap_or("");
let assets = release["assets"]
.as_array()
.ok_or_else(|| format_err!(Error::Release, "No assets found"))?;
.ok_or_else(|| format_err!(crate::ErrorKind::Network, "No assets found"))?;
let assets = assets
.iter()
.map(ReleaseAsset::from_asset)
.collect::<Result<Vec<ReleaseAsset>, Error>>()?;
.collect::<crate::Result<Vec<ReleaseAsset>>>()?;
Ok(Release {
name: name.to_owned(),
body: body.to_owned(),
@ -109,17 +112,17 @@ impl ReleaseListBuilder {
}
/// Verify builder args, returning a `ReleaseList`
pub fn build(&self) -> Result<ReleaseList, Error> {
pub fn build(&self) -> crate::Result<ReleaseList> {
Ok(ReleaseList {
repo_owner: if let Some(ref owner) = self.repo_owner {
owner.to_owned()
} else {
bail!(Error::Config, "`repo_owner` required")
bail!(crate::ErrorKind::Config, "`repo_owner` required")
},
repo_name: if let Some(ref name) = self.repo_name {
name.to_owned()
} else {
bail!(Error::Config, "`repo_name` required")
bail!(crate::ErrorKind::Config, "`repo_name` required")
},
target: self.target.clone(),
})
@ -146,7 +149,7 @@ impl ReleaseList {
/// Retrieve a list of `Release`s.
/// If specified, filter for those containing a specified `target`
pub fn fetch(self) -> Result<Vec<Release>, Error> {
pub fn fetch(self) -> crate::Result<Vec<Release>> {
set_ssl_vars!();
let api_url = format!(
"https://api.github.com/repos/{}/{}/releases",
@ -163,29 +166,30 @@ impl ReleaseList {
Ok(releases)
}
fn fetch_releases(url: &str) -> Result<Vec<Release>, Error> {
let mut resp = reqwest::get(url)?;
if !resp.status().is_success() {
fn fetch_releases(url: &str) -> crate::Result<Vec<Release>> {
let (status, headers, reader) = attohttpc::get(url).send()?.split();
if !status.is_success() {
bail!(
Error::Network,
crate::ErrorKind::Network,
"api request failed with status: {:?} - for: {:?}",
resp.status(),
status,
url
)
}
let releases = resp.json::<serde_json::Value>()?;
let releases = reader.json::<serde_json::Value>()?.clone();
let releases = releases
.as_array()
.ok_or_else(|| format_err!(Error::Release, "No releases found"))?;
.ok_or_else(|| format_err!(crate::ErrorKind::Network, "No releases found"))?;
let mut releases = releases
.iter()
.map(Release::parse)
.collect::<Result<Vec<Release>, Error>>()?;
.collect::<crate::Result<Vec<Release>>>()?;
// handle paged responses containing `Link` header:
// `Link: <https://api.github.com/resource?page=2>; rel="next"`
let headers = resp.headers();
let links = headers.get_all(reqwest::header::LINK);
let links = headers.get_all(attohttpc::header::LINK);
let next_link = links
.iter()

14
tauri-utils/Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "tauri-utils"
version = "0.3.0"
authors = ["Lucas Fernandes Gonçalves Nogueira <lucas@quasar.dev>", "Daniel Thompson-Yvetot <denjell@sfosc.org>", "Tensor Programming <tensordeveloper@gmail.com>"]
license = "MIT"
homepage = "https://tauri-apps.org"
repository = "https://github.com/tauri-apps/tauri"
description = "Utilities for Tauri"
edition = "2018"
[dependencies]
sysinfo = "0.10"
error-chain = "0.12.1"

8
tauri-utils/src/lib.rs Normal file
View File

@ -0,0 +1,8 @@
pub mod platform;
pub mod process;
use error_chain::error_chain;
error_chain! {
errors{}
}

View File

@ -7,7 +7,7 @@
///
/// * Errors:
/// * Unexpected system config
pub(crate) fn target_triple() -> Result<String, crate::Error> {
pub fn target_triple() -> Result<String, crate::Error> {
let arch = if cfg!(target_arch = "x86") {
"i686"
} else if cfg!(target_arch = "x86_64") {
@ -15,7 +15,9 @@ pub(crate) fn target_triple() -> Result<String, crate::Error> {
} else if cfg!(target_arch = "arm") {
"armv7"
} else {
return Err(crate::Error::from("Unable to determine target-architecture"));
return Err(crate::Error::from(
"Unable to determine target-architecture",
));
};
let os = if cfg!(target_os = "linux") {
@ -48,4 +50,4 @@ pub(crate) fn target_triple() -> Result<String, crate::Error> {
};
Ok(format!("{}-{}", arch, os))
}
}

View File

@ -2,7 +2,7 @@ use sysinfo;
pub use sysinfo::{Process, ProcessExt, Signal, System, SystemExt};
pub fn get_parent_process(system: &mut sysinfo::System) -> Result<&Process, String> {
pub fn get_parent_process(system: &mut sysinfo::System) -> crate::Result<&Process> {
let pid = sysinfo::get_current_pid().unwrap();
system.refresh_process(pid);
let current_process = system

View File

@ -23,6 +23,7 @@ lazy_static = "1.4.0"
tiny_http = "0.6"
threadpool = "1.7"
uuid = { version = "0.8.1", features = ["v4"] }
tauri-api = { version = "0.3", path = "../tauri-api" }
[build-dependencies]