cleanup builder, fix installer and test on linux

pull/431/head
Lucas Nogueira 2 years ago
parent 9c80db5530
commit b36c6001ec
No known key found for this signature in database
GPG Key ID: FFEA6C72E73482F1

177
Cargo.lock generated

@ -100,15 +100,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "aho-corasick"
version = "1.0.1"
@ -390,28 +381,6 @@ dependencies = [
"syn 2.0.18",
]
[[package]]
name = "async-stream"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51"
dependencies = [
"async-stream-impl",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-stream-impl"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.18",
]
[[package]]
name = "async-task"
version = "4.4.0"
@ -638,16 +607,6 @@ dependencies = [
"alloc-stdlib",
]
[[package]]
name = "bstr"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "bumpalo"
version = "3.13.0"
@ -695,6 +654,27 @@ dependencies = [
"serde",
]
[[package]]
name = "bzip2"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
dependencies = [
"bzip2-sys",
"libc",
]
[[package]]
name = "bzip2-sys"
version = "0.1.11+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]]
name = "cairo-rs"
version = "0.16.7"
@ -735,6 +715,9 @@ name = "cc"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
dependencies = [
"jobserver",
]
[[package]]
name = "cesu8"
@ -1988,19 +1971,6 @@ dependencies = [
"x11-dl",
]
[[package]]
name = "globset"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc"
dependencies = [
"aho-corasick 0.7.20",
"bstr",
"fnv",
"log",
"regex",
]
[[package]]
name = "gobject-sys"
version = "0.16.3"
@ -2342,23 +2312,6 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "ignore"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492"
dependencies = [
"globset",
"lazy_static",
"log",
"memchr",
"regex",
"same-file",
"thread_local",
"walkdir",
"winapi-util",
]
[[package]]
name = "image"
version = "0.24.6"
@ -2615,6 +2568,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jobserver"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
dependencies = [
"libc",
]
[[package]]
name = "jpeg-decoder"
version = "0.3.0"
@ -3488,6 +3450,17 @@ dependencies = [
"windows-sys 0.45.0",
]
[[package]]
name = "password-hash"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
dependencies = [
"base64ct",
"rand_core 0.6.4",
"subtle",
]
[[package]]
name = "paste"
version = "1.0.12"
@ -3507,6 +3480,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
dependencies = [
"digest 0.10.7",
"hmac",
"password-hash",
"sha2 0.10.6",
]
[[package]]
@ -3987,7 +3963,7 @@ version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390"
dependencies = [
"aho-corasick 1.0.1",
"aho-corasick",
"memchr",
"regex-syntax 0.7.2",
]
@ -5300,7 +5276,7 @@ dependencies = [
name = "tauri-plugin-persisted-scope"
version = "2.0.0-alpha.0"
dependencies = [
"aho-corasick 1.0.1",
"aho-corasick",
"bincode",
"log",
"serde",
@ -5407,10 +5383,8 @@ version = "2.0.0-alpha.0"
dependencies = [
"base64 0.21.2",
"dirs-next",
"flate2",
"futures-util",
"http",
"ignore",
"minisign-verify",
"mockito",
"percent-encoding",
@ -5424,7 +5398,6 @@ dependencies = [
"thiserror",
"time 0.3.21",
"tokio",
"tokio-test",
"url",
"zip",
]
@ -5786,19 +5759,6 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-test"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53474327ae5e166530d17f2d956afcb4f8a004de581b3cae10f12006bc8163e3"
dependencies = [
"async-stream",
"bytes 1.4.0",
"futures-core",
"tokio",
"tokio-stream",
]
[[package]]
name = "tokio-tungstenite"
version = "0.19.0"
@ -7033,9 +6993,48 @@ version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
dependencies = [
"aes 0.8.2",
"byteorder",
"bzip2",
"constant_time_eq 0.1.5",
"crc32fast",
"crossbeam-utils",
"flate2",
"hmac",
"pbkdf2",
"sha1",
"time 0.3.21",
"zstd",
]
[[package]]
name = "zstd"
version = "0.11.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "5.0.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
dependencies = [
"libc",
"zstd-sys",
]
[[package]]
name = "zstd-sys"
version = "2.0.8+zstd.1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]]

@ -63,11 +63,13 @@ impl<R: Runtime, T: Manager<R>> UpdaterExt<R> for T {
let version = app.package_info().version.clone();
let updater_config = app.config().tauri.bundle.updater.clone();
let UpdaterState { config, target } = self.state::<UpdaterState>().inner();
#[allow(unused_mut)]
let mut builder = UpdaterBuilder::new(version, config.clone(), updater_config);
if let Some(target) = target {
builder = builder.target(target);
}
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
@ -78,9 +80,10 @@ impl<R: Runtime, T: Manager<R>> UpdaterExt<R> for T {
{
let env = app.env();
if let Some(appimage) = env.appimage {
builder = builder.app_image_path(appimage);
builder = builder.executable_path(appimage);
}
}
builder
}

@ -85,10 +85,16 @@ impl RemoteRelease {
}
pub struct UpdaterBuilder {
updater: Updater,
target: Option<String>,
current_version: Version,
config: crate::Config,
updater_config: UpdaterConfig,
version_comparator: Option<Box<dyn Fn(Version, RemoteRelease) -> bool + Send + Sync>>,
executable_path: Option<PathBuf>,
app_image_path: Option<PathBuf>,
target: Option<String>,
endpoints: Option<Vec<Url>>,
headers: HeaderMap,
timeout: Option<Duration>,
installer_args: Option<Vec<String>>,
}
impl UpdaterBuilder {
@ -98,10 +104,16 @@ impl UpdaterBuilder {
updater_config: UpdaterConfig,
) -> Self {
Self {
updater: Updater::new(current_version, config, updater_config),
target: Default::default(),
executable_path: Default::default(),
app_image_path: Default::default(),
current_version,
config,
updater_config,
version_comparator: None,
executable_path: None,
target: None,
endpoints: None,
headers: Default::default(),
timeout: None,
installer_args: None,
}
}
@ -109,24 +121,25 @@ impl UpdaterBuilder {
mut self,
f: F,
) -> Self {
self.updater.version_comparator = Some(Box::new(f));
self.version_comparator = Some(Box::new(f));
self
}
pub fn target(mut self, target: impl Into<String>) -> Self {
self.target = Some(target.into());
self.target.replace(target.into());
self
}
pub fn endpoints(mut self, endpoints: Vec<Url>) -> Self {
self.updater.endpoints = endpoints;
self.endpoints.replace(endpoints);
self
}
pub fn executable_path<P: AsRef<Path>>(mut self, p: P) -> Self {
self.executable_path = Some(PathBuf::from(p.as_ref()));
self.executable_path.replace(p.as_ref().into());
self
}
pub fn header<K, V>(mut self, key: K, value: V) -> Result<Self>
where
HeaderName: TryFrom<K>,
@ -137,17 +150,13 @@ impl UpdaterBuilder {
let key: std::result::Result<HeaderName, http::Error> = key.try_into().map_err(Into::into);
let value: std::result::Result<HeaderValue, http::Error> =
value.try_into().map_err(Into::into);
self.updater.headers_map.insert(key?, value?);
self.headers.insert(key?, value?);
Ok(self)
}
pub fn timeout(mut self, timeout: Duration) -> Self {
self.updater.timeout = Some(timeout);
self
}
pub fn app_image_path<P: AsRef<Path>>(mut self, p: P) -> Self {
self.app_image_path = Some(PathBuf::from(p.as_ref()));
self.timeout = Some(timeout);
self
}
@ -156,71 +165,74 @@ impl UpdaterBuilder {
I: IntoIterator<Item = S>,
S: Into<String>,
{
self.updater.config.installer_args = args.into_iter().map(Into::into).collect();
self.installer_args
.replace(args.into_iter().map(Into::into).collect());
self
}
pub fn build(mut self) -> Result<Updater> {
if self.updater.endpoints.is_empty() {
pub fn build(self) -> Result<Updater> {
let endpoints = self
.endpoints
.unwrap_or_else(|| self.config.endpoints.into_iter().map(|e| e.0).collect());
if endpoints.is_empty() {
return Err(Error::EmptyEndpoints);
};
let executable_path = self.executable_path.clone().unwrap_or(current_exe()?);
let arch = get_updater_arch().ok_or(Error::UnsupportedArch)?;
// `target` is the `{{target}}` variable we replace in the endpoint
// `json_target` is the value we search if the updater server returns a JSON with the `platforms` object
(self.updater.target, self.updater.json_target) = match self.target {
Some(target) => (target.clone(), target),
None => {
let target = get_updater_target().ok_or(Error::UnsupportedOs)?;
(target.to_string(), format!("{target}-{arch}"))
}
let (target, json_target) = if let Some(target) = self.target {
(target.clone(), target)
} else {
let target = get_updater_target().ok_or(Error::UnsupportedOs)?;
(target.to_string(), format!("{target}-{arch}"))
};
let executable_path = self.executable_path.clone().unwrap_or(current_exe()?);
// Get the extract_path from the provided executable_path
self.updater.extract_path =
extract_path_from_executable(&executable_path, self.app_image_path)?;
let extract_path = if cfg!(target_os = "linux") {
executable_path
} else {
extract_path_from_executable(&executable_path)?
};
Ok(self.updater)
Ok(Updater {
config: self.updater_config,
current_version: self.current_version,
version_comparator: self.version_comparator,
timeout: self.timeout,
endpoints,
installer_args: self.installer_args.unwrap_or(self.config.installer_args),
arch,
target,
json_target,
headers: self.headers,
extract_path,
})
}
}
pub struct Updater {
config: UpdaterConfig,
current_version: Version,
version_comparator: Option<Box<dyn Fn(Version, RemoteRelease) -> bool + Send + Sync>>,
timeout: Option<Duration>,
endpoints: Vec<Url>,
arch: String,
#[allow(dead_code)]
installer_args: Vec<String>,
arch: &'static str,
// The `{{target}}` variable we replace in the endpoint
target: String,
// The value we search if the updater server returns a JSON with the `platforms` object
json_target: String,
headers_map: HeaderMap,
headers: HeaderMap,
extract_path: PathBuf,
config: crate::Config,
updater_config: UpdaterConfig,
}
impl Updater {
fn new(current_version: Version, config: crate::Config, updater_config: UpdaterConfig) -> Self {
Self {
current_version,
version_comparator: Default::default(),
timeout: Default::default(),
endpoints: Default::default(),
arch: Default::default(),
target: Default::default(),
headers_map: Default::default(),
extract_path: Default::default(),
json_target: Default::default(),
config,
updater_config,
}
}
pub async fn check(&self) -> Result<Option<Update>> {
// we want JSON only
let mut headers = self.headers_map.clone();
let mut headers = self.headers.clone();
headers.insert("Accept", HeaderValue::from_str("application/json").unwrap());
// Set SSL certs for linux if they aren't available.
@ -248,7 +260,7 @@ impl Updater {
.to_string()
.replace("{{current_version}}", &self.current_version.to_string())
.replace("{{target}}", &self.target)
.replace("{{arch}}", &self.arch)
.replace("{{arch}}", self.arch)
.parse()?;
let mut request = Client::new().get(url).headers(headers.clone());
@ -295,9 +307,8 @@ impl Updater {
let update = if should_update {
Some(Update {
config: self.config.clone(),
current_version: self.current_version.to_string(),
updater_config: self.updater_config.clone(),
config: self.config.clone(),
target: self.target.clone(),
extract_path: self.extract_path.clone(),
version: release.version.to_string(),
@ -306,7 +317,7 @@ impl Updater {
body: release.notes.clone(),
signature: release.signature(&self.json_target)?.to_owned(),
timeout: self.timeout,
headers: self.headers_map.clone(),
headers: self.headers.clone(),
})
} else {
None
@ -318,9 +329,7 @@ impl Updater {
#[derive(Debug, Clone)]
pub struct Update {
#[allow(unused)]
config: crate::Config,
updater_config: UpdaterConfig,
config: UpdaterConfig,
/// Update description
pub body: Option<String>,
/// Version used to check for update
@ -399,11 +408,7 @@ impl Update {
let mut update_buffer = Cursor::new(&buffer);
verify_signature(
&mut update_buffer,
&self.signature,
&self.updater_config.pubkey,
)?;
verify_signature(&mut update_buffer, &self.signature, &self.config.pubkey)?;
Ok(buffer)
}
@ -475,8 +480,8 @@ impl Update {
if found_path.extension() == Some(OsStr::new("exe")) {
// Run the EXE
Command::new(found_path)
.args(self.updater_config.windows.install_mode.nsis_args())
.args(&self.config.installer_args)
.args(self.config.windows.install_mode.nsis_args())
.args(&self.installer_args)
.spawn()
.expect("installer failed to start");
@ -494,7 +499,7 @@ impl Update {
msi_path_arg.push("\"\"\"");
let msiexec_args = self
.updater_config
.config
.windows
.install_mode
.msiexec_args()
@ -595,7 +600,7 @@ impl Update {
// extract the buffer to the tmp_dir
// we extract our signed archive into our final directory without any temp file
let mut archive = tar::Archive::new(archive.clone());
let mut archive = tar::Archive::new(archive);
for mut entry in archive.entries()?.flatten() {
if let Ok(path) = entry.path() {
if path.extension() == Some(OsStr::new("AppImage")) {
@ -609,6 +614,8 @@ impl Update {
}
}
}
return Ok(());
}
}
}
@ -707,10 +714,7 @@ pub(crate) fn get_updater_arch() -> Option<&'static str> {
}
}
pub fn extract_path_from_executable(
executable_path: &Path,
_app_image_path: Option<PathBuf>,
) -> Result<PathBuf> {
pub fn extract_path_from_executable(executable_path: &Path) -> Result<PathBuf> {
// Return the path of the current executable by default
// Example C:\Program Files\My App\
let extract_path = executable_path
@ -737,13 +741,6 @@ pub fn extract_path_from_executable(
.ok_or(Error::FailedToDetermineExtractPath);
}
// We should use APPIMAGE exposed env variable
// This is where our APPIMAGE should sit and should be replaced
#[cfg(target_os = "linux")]
if let Some(app_image_path) = _app_image_path {
return Ok(app_image_path);
}
Ok(extract_path)
}

@ -115,7 +115,7 @@ impl Default for BundleTarget {
#[cfg(any(target_os = "macos", target_os = "ios"))]
return Self::App;
#[cfg(target_os = "linux")]
return Self::App;
return Self::AppImage;
#[cfg(windows)]
return Self::Nsis;
}

Loading…
Cancel
Save