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", "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]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "1.0.1" version = "1.0.1"
@ -390,28 +381,6 @@ dependencies = [
"syn 2.0.18", "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]] [[package]]
name = "async-task" name = "async-task"
version = "4.4.0" version = "4.4.0"
@ -638,16 +607,6 @@ dependencies = [
"alloc-stdlib", "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]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.13.0" version = "3.13.0"
@ -695,6 +654,27 @@ dependencies = [
"serde", "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]] [[package]]
name = "cairo-rs" name = "cairo-rs"
version = "0.16.7" version = "0.16.7"
@ -735,6 +715,9 @@ name = "cc"
version = "1.0.79" version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
dependencies = [
"jobserver",
]
[[package]] [[package]]
name = "cesu8" name = "cesu8"
@ -1988,19 +1971,6 @@ dependencies = [
"x11-dl", "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]] [[package]]
name = "gobject-sys" name = "gobject-sys"
version = "0.16.3" version = "0.16.3"
@ -2342,23 +2312,6 @@ dependencies = [
"unicode-normalization", "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]] [[package]]
name = "image" name = "image"
version = "0.24.6" version = "0.24.6"
@ -2615,6 +2568,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jobserver"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "jpeg-decoder" name = "jpeg-decoder"
version = "0.3.0" version = "0.3.0"
@ -3488,6 +3450,17 @@ dependencies = [
"windows-sys 0.45.0", "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]] [[package]]
name = "paste" name = "paste"
version = "1.0.12" version = "1.0.12"
@ -3507,6 +3480,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
dependencies = [ dependencies = [
"digest 0.10.7", "digest 0.10.7",
"hmac",
"password-hash",
"sha2 0.10.6",
] ]
[[package]] [[package]]
@ -3987,7 +3963,7 @@ version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390"
dependencies = [ dependencies = [
"aho-corasick 1.0.1", "aho-corasick",
"memchr", "memchr",
"regex-syntax 0.7.2", "regex-syntax 0.7.2",
] ]
@ -5300,7 +5276,7 @@ dependencies = [
name = "tauri-plugin-persisted-scope" name = "tauri-plugin-persisted-scope"
version = "2.0.0-alpha.0" version = "2.0.0-alpha.0"
dependencies = [ dependencies = [
"aho-corasick 1.0.1", "aho-corasick",
"bincode", "bincode",
"log", "log",
"serde", "serde",
@ -5407,10 +5383,8 @@ version = "2.0.0-alpha.0"
dependencies = [ dependencies = [
"base64 0.21.2", "base64 0.21.2",
"dirs-next", "dirs-next",
"flate2",
"futures-util", "futures-util",
"http", "http",
"ignore",
"minisign-verify", "minisign-verify",
"mockito", "mockito",
"percent-encoding", "percent-encoding",
@ -5424,7 +5398,6 @@ dependencies = [
"thiserror", "thiserror",
"time 0.3.21", "time 0.3.21",
"tokio", "tokio",
"tokio-test",
"url", "url",
"zip", "zip",
] ]
@ -5786,19 +5759,6 @@ dependencies = [
"tokio", "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]] [[package]]
name = "tokio-tungstenite" name = "tokio-tungstenite"
version = "0.19.0" version = "0.19.0"
@ -7033,9 +6993,48 @@ version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
dependencies = [ dependencies = [
"aes 0.8.2",
"byteorder", "byteorder",
"bzip2",
"constant_time_eq 0.1.5",
"crc32fast", "crc32fast",
"crossbeam-utils", "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]] [[package]]

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

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

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

Loading…
Cancel
Save