mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-12-25 19:54:07 +03:00
refactor(core): load APPIMAGE and APPDIR env vars on startup [TRI-007] [TRI-041]
This commit is contained in:
parent
4de285c396
commit
7209fdf732
5
.changes/core-env.md
Normal file
5
.changes/core-env.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"tauri": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
The `process`, `path` and `updater` APIs now takes a `tauri::Env` argument, used to force environment variables load on startup to prevent env var update attacks.
|
@ -37,6 +37,28 @@ impl PackageInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Information about environment variables.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Env {
|
||||||
|
/// The APPIMAGE environment variable.
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub appimage: Option<std::ffi::OsString>,
|
||||||
|
/// The APPDIR environment variable.
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub appdir: Option<std::ffi::OsString>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Env {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
appimage: std::env::var_os("APPIMAGE"),
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
appdir: std::env::var_os("APPDIR"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The result type of `tauri-utils`.
|
/// The result type of `tauri-utils`.
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
@ -4,12 +4,9 @@
|
|||||||
|
|
||||||
//! Platform helper functions.
|
//! Platform helper functions.
|
||||||
|
|
||||||
use std::{
|
use std::path::{PathBuf, MAIN_SEPARATOR};
|
||||||
env,
|
|
||||||
path::{PathBuf, MAIN_SEPARATOR},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::PackageInfo;
|
use crate::{Env, PackageInfo};
|
||||||
|
|
||||||
/// Try to determine the current target triple.
|
/// Try to determine the current target triple.
|
||||||
///
|
///
|
||||||
@ -76,7 +73,7 @@ pub fn target_triple() -> crate::Result<String> {
|
|||||||
/// `${exe_dir}/../lib/${exe_name}`.
|
/// `${exe_dir}/../lib/${exe_name}`.
|
||||||
///
|
///
|
||||||
/// On MacOS, it's `${exe_dir}../Resources` (inside .app).
|
/// On MacOS, it's `${exe_dir}../Resources` (inside .app).
|
||||||
pub fn resource_dir(package_info: &PackageInfo) -> crate::Result<PathBuf> {
|
pub fn resource_dir(package_info: &PackageInfo, env: &Env) -> crate::Result<PathBuf> {
|
||||||
let exe = std::env::current_exe()?;
|
let exe = std::env::current_exe()?;
|
||||||
let exe_dir = exe.parent().expect("failed to get exe directory");
|
let exe_dir = exe.parent().expect("failed to get exe directory");
|
||||||
let curr_dir = exe_dir.display().to_string();
|
let curr_dir = exe_dir.display().to_string();
|
||||||
@ -93,10 +90,11 @@ pub fn resource_dir(package_info: &PackageInfo) -> crate::Result<PathBuf> {
|
|||||||
if curr_dir.ends_with("/data/usr/bin") {
|
if curr_dir.ends_with("/data/usr/bin") {
|
||||||
// running from the deb bundle dir
|
// running from the deb bundle dir
|
||||||
Ok(exe_dir.join(format!("../lib/{}", package_info.package_name())))
|
Ok(exe_dir.join(format!("../lib/{}", package_info.package_name())))
|
||||||
} else if let Ok(appdir) = env::var("APPDIR") {
|
} else if let Some(appdir) = &env.appdir {
|
||||||
|
let appdir: &std::path::Path = appdir.as_ref();
|
||||||
Ok(PathBuf::from(format!(
|
Ok(PathBuf::from(format!(
|
||||||
"{}/usr/lib/{}",
|
"{}/usr/lib/{}",
|
||||||
appdir,
|
appdir.display(),
|
||||||
package_info.package_name()
|
package_info.package_name()
|
||||||
)))
|
)))
|
||||||
} else {
|
} else {
|
||||||
|
@ -9,7 +9,7 @@ use std::{
|
|||||||
path::{Component, Path, PathBuf},
|
path::{Component, Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Config, PackageInfo};
|
use crate::{Config, Env, PackageInfo};
|
||||||
|
|
||||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||||
|
|
||||||
@ -83,6 +83,7 @@ pub enum BaseDirectory {
|
|||||||
/// authors: "tauri",
|
/// authors: "tauri",
|
||||||
/// description: "a tauri test",
|
/// description: "a tauri test",
|
||||||
/// },
|
/// },
|
||||||
|
/// &Default::default(),
|
||||||
/// "path/to/something",
|
/// "path/to/something",
|
||||||
/// Some(BaseDirectory::Config)
|
/// Some(BaseDirectory::Config)
|
||||||
/// ).expect("failed to resolve path");
|
/// ).expect("failed to resolve path");
|
||||||
@ -91,6 +92,7 @@ pub enum BaseDirectory {
|
|||||||
pub fn resolve_path<P: AsRef<Path>>(
|
pub fn resolve_path<P: AsRef<Path>>(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
path: P,
|
path: P,
|
||||||
dir: Option<BaseDirectory>,
|
dir: Option<BaseDirectory>,
|
||||||
) -> crate::api::Result<PathBuf> {
|
) -> crate::api::Result<PathBuf> {
|
||||||
@ -113,7 +115,7 @@ pub fn resolve_path<P: AsRef<Path>>(
|
|||||||
BaseDirectory::Runtime => runtime_dir(),
|
BaseDirectory::Runtime => runtime_dir(),
|
||||||
BaseDirectory::Template => template_dir(),
|
BaseDirectory::Template => template_dir(),
|
||||||
BaseDirectory::Video => video_dir(),
|
BaseDirectory::Video => video_dir(),
|
||||||
BaseDirectory::Resource => resource_dir(package_info),
|
BaseDirectory::Resource => resource_dir(package_info, env),
|
||||||
BaseDirectory::App => app_dir(config),
|
BaseDirectory::App => app_dir(config),
|
||||||
BaseDirectory::Current => Some(env::current_dir()?),
|
BaseDirectory::Current => Some(env::current_dir()?),
|
||||||
BaseDirectory::Log => log_dir(config),
|
BaseDirectory::Log => log_dir(config),
|
||||||
@ -229,8 +231,8 @@ pub fn video_dir() -> Option<PathBuf> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path to the resource directory of this app.
|
/// Returns the path to the resource directory of this app.
|
||||||
pub fn resource_dir(package_info: &PackageInfo) -> Option<PathBuf> {
|
pub fn resource_dir(package_info: &PackageInfo, env: &Env) -> Option<PathBuf> {
|
||||||
crate::utils::platform::resource_dir(package_info).ok()
|
crate::utils::platform::resource_dir(package_info, env).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path to the suggested directory for your app config files.
|
/// Returns the path to the suggested directory for your app config files.
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
//! Types and functions related to child processes management.
|
//! Types and functions related to child processes management.
|
||||||
|
|
||||||
|
use crate::Env;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
@ -16,12 +18,13 @@ mod command;
|
|||||||
pub use command::*;
|
pub use command::*;
|
||||||
|
|
||||||
/// Gets the current binary.
|
/// Gets the current binary.
|
||||||
pub fn current_binary() -> Option<PathBuf> {
|
#[allow(unused_variables)]
|
||||||
|
pub fn current_binary(env: &Env) -> Option<PathBuf> {
|
||||||
let mut current_binary = None;
|
let mut current_binary = None;
|
||||||
|
|
||||||
// if we are running with an APP Image, we should return the app image path
|
// if we are running with an APP Image, we should return the app image path
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
if let Some(app_image_path) = env::var_os("APPIMAGE") {
|
if let Some(app_image_path) = &env.appimage {
|
||||||
current_binary = Some(PathBuf::from(app_image_path));
|
current_binary = Some(PathBuf::from(app_image_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,8 +40,8 @@ pub fn current_binary() -> Option<PathBuf> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Restarts the process.
|
/// Restarts the process.
|
||||||
pub fn restart() {
|
pub fn restart(env: &Env) {
|
||||||
if let Some(path) = current_binary() {
|
if let Some(path) = current_binary(env) {
|
||||||
StdCommand::new(path)
|
StdCommand::new(path)
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("application failed to start");
|
.expect("application failed to start");
|
||||||
|
@ -19,8 +19,8 @@ use crate::{
|
|||||||
Dispatch, ExitRequestedEventAction, RunEvent, Runtime,
|
Dispatch, ExitRequestedEventAction, RunEvent, Runtime,
|
||||||
},
|
},
|
||||||
sealed::{ManagerBase, RuntimeOrDispatch},
|
sealed::{ManagerBase, RuntimeOrDispatch},
|
||||||
utils::assets::Assets,
|
|
||||||
utils::config::{Config, WindowUrl},
|
utils::config::{Config, WindowUrl},
|
||||||
|
utils::{assets::Assets, Env},
|
||||||
Context, Invoke, InvokeError, InvokeResponse, Manager, StateManager, Window,
|
Context, Invoke, InvokeError, InvokeResponse, Manager, StateManager, Window,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -150,6 +150,7 @@ impl<R: Runtime> GlobalWindowEvent<R> {
|
|||||||
/// The path resolver is a helper for the application-specific [`crate::api::path`] APIs.
|
/// The path resolver is a helper for the application-specific [`crate::api::path`] APIs.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct PathResolver {
|
pub struct PathResolver {
|
||||||
|
env: Env,
|
||||||
config: Arc<Config>,
|
config: Arc<Config>,
|
||||||
package_info: PackageInfo,
|
package_info: PackageInfo,
|
||||||
}
|
}
|
||||||
@ -157,7 +158,7 @@ pub struct PathResolver {
|
|||||||
impl PathResolver {
|
impl PathResolver {
|
||||||
/// Returns the path to the resource directory of this app.
|
/// Returns the path to the resource directory of this app.
|
||||||
pub fn resource_dir(&self) -> Option<PathBuf> {
|
pub fn resource_dir(&self) -> Option<PathBuf> {
|
||||||
crate::api::path::resource_dir(&self.package_info)
|
crate::api::path::resource_dir(&self.package_info, &self.env)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path to the suggested directory for your app config files.
|
/// Returns the path to the suggested directory for your app config files.
|
||||||
@ -407,6 +408,7 @@ macro_rules! shared_app_impl {
|
|||||||
/// The path resolver for the application.
|
/// The path resolver for the application.
|
||||||
pub fn path_resolver(&self) -> PathResolver {
|
pub fn path_resolver(&self) -> PathResolver {
|
||||||
PathResolver {
|
PathResolver {
|
||||||
|
env: self.state::<Env>().inner().clone(),
|
||||||
config: self.manager.config(),
|
config: self.manager.config(),
|
||||||
package_info: self.manager.package_info().clone(),
|
package_info: self.manager.package_info().clone(),
|
||||||
}
|
}
|
||||||
@ -432,6 +434,11 @@ macro_rules! shared_app_impl {
|
|||||||
self.manager.package_info()
|
self.manager.package_info()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the managed [`Env`].
|
||||||
|
pub fn env(&self) -> Env {
|
||||||
|
self.state::<Env>().inner().clone()
|
||||||
|
}
|
||||||
|
|
||||||
/// The application's asset resolver.
|
/// The application's asset resolver.
|
||||||
pub fn asset_resolver(&self) -> AssetResolver<R> {
|
pub fn asset_resolver(&self) -> AssetResolver<R> {
|
||||||
AssetResolver {
|
AssetResolver {
|
||||||
@ -990,6 +997,8 @@ impl<R: Runtime> Builder<R> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
app.manage(Env::default());
|
||||||
|
|
||||||
#[cfg(feature = "system-tray")]
|
#[cfg(feature = "system-tray")]
|
||||||
if let Some(system_tray) = self.system_tray {
|
if let Some(system_tray) = self.system_tray {
|
||||||
let mut ids = HashMap::new();
|
let mut ids = HashMap::new();
|
||||||
|
@ -75,17 +75,21 @@ impl Module {
|
|||||||
.and_then(|r| r.json)
|
.and_then(|r| r.json)
|
||||||
.map_err(InvokeError::from)
|
.map_err(InvokeError::from)
|
||||||
}),
|
}),
|
||||||
Self::Process(cmd) => resolver
|
Self::Process(cmd) => resolver.respond_async(async move {
|
||||||
.respond_async(async move { cmd.run().and_then(|r| r.json).map_err(InvokeError::from) }),
|
cmd
|
||||||
|
.run(window)
|
||||||
|
.and_then(|r| r.json)
|
||||||
|
.map_err(InvokeError::from)
|
||||||
|
}),
|
||||||
Self::Fs(cmd) => resolver.respond_async(async move {
|
Self::Fs(cmd) => resolver.respond_async(async move {
|
||||||
cmd
|
cmd
|
||||||
.run(config, &package_info)
|
.run(window, config, &package_info)
|
||||||
.and_then(|r| r.json)
|
.and_then(|r| r.json)
|
||||||
.map_err(InvokeError::from)
|
.map_err(InvokeError::from)
|
||||||
}),
|
}),
|
||||||
Self::Path(cmd) => resolver.respond_async(async move {
|
Self::Path(cmd) => resolver.respond_async(async move {
|
||||||
cmd
|
cmd
|
||||||
.run(config, &package_info)
|
.run(window, config, &package_info)
|
||||||
.and_then(|r| r.json)
|
.and_then(|r| r.json)
|
||||||
.map_err(InvokeError::from)
|
.map_err(InvokeError::from)
|
||||||
}),
|
}),
|
||||||
|
@ -8,7 +8,7 @@ use crate::{
|
|||||||
dir, file,
|
dir, file,
|
||||||
path::{resolve_path, BaseDirectory},
|
path::{resolve_path, BaseDirectory},
|
||||||
},
|
},
|
||||||
Config, PackageInfo,
|
Config, Env, Manager, PackageInfo, Runtime, Window,
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -97,15 +97,17 @@ pub enum Cmd {
|
|||||||
|
|
||||||
impl Cmd {
|
impl Cmd {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub fn run(
|
pub fn run<R: Runtime>(
|
||||||
self,
|
self,
|
||||||
|
window: Window<R>,
|
||||||
config: Arc<Config>,
|
config: Arc<Config>,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
) -> crate::Result<InvokeResponse> {
|
) -> crate::Result<InvokeResponse> {
|
||||||
|
let env = window.state::<Env>().inner();
|
||||||
match self {
|
match self {
|
||||||
#[cfg(fs_read_text_file)]
|
#[cfg(fs_read_text_file)]
|
||||||
Self::ReadTextFile { path, options } => {
|
Self::ReadTextFile { path, options } => {
|
||||||
read_text_file(&config, package_info, path, options).map(Into::into)
|
read_text_file(&config, package_info, env, path, options).map(Into::into)
|
||||||
}
|
}
|
||||||
#[cfg(not(fs_read_text_file))]
|
#[cfg(not(fs_read_text_file))]
|
||||||
Self::ReadTextFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
Self::ReadTextFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
||||||
@ -114,7 +116,7 @@ impl Cmd {
|
|||||||
|
|
||||||
#[cfg(fs_read_binary_file)]
|
#[cfg(fs_read_binary_file)]
|
||||||
Self::ReadBinaryFile { path, options } => {
|
Self::ReadBinaryFile { path, options } => {
|
||||||
read_binary_file(&config, package_info, path, options).map(Into::into)
|
read_binary_file(&config, package_info, env, path, options).map(Into::into)
|
||||||
}
|
}
|
||||||
#[cfg(not(fs_read_binary_file))]
|
#[cfg(not(fs_read_binary_file))]
|
||||||
Self::ReadBinaryFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
Self::ReadBinaryFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
||||||
@ -126,7 +128,7 @@ impl Cmd {
|
|||||||
path,
|
path,
|
||||||
contents,
|
contents,
|
||||||
options,
|
options,
|
||||||
} => write_file(&config, package_info, path, contents, options).map(Into::into),
|
} => write_file(&config, package_info, env, path, contents, options).map(Into::into),
|
||||||
#[cfg(not(fs_write_file))]
|
#[cfg(not(fs_write_file))]
|
||||||
Self::WriteFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
Self::WriteFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
||||||
"fs > writeFile".to_string(),
|
"fs > writeFile".to_string(),
|
||||||
@ -137,7 +139,7 @@ impl Cmd {
|
|||||||
path,
|
path,
|
||||||
contents,
|
contents,
|
||||||
options,
|
options,
|
||||||
} => write_binary_file(&config, package_info, path, contents, options).map(Into::into),
|
} => write_binary_file(&config, package_info, env, path, contents, options).map(Into::into),
|
||||||
#[cfg(not(fs_write_binary_file))]
|
#[cfg(not(fs_write_binary_file))]
|
||||||
Self::WriteBinaryFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
Self::WriteBinaryFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
||||||
"writeBinaryFile".to_string(),
|
"writeBinaryFile".to_string(),
|
||||||
@ -145,7 +147,7 @@ impl Cmd {
|
|||||||
|
|
||||||
#[cfg(fs_read_dir)]
|
#[cfg(fs_read_dir)]
|
||||||
Self::ReadDir { path, options } => {
|
Self::ReadDir { path, options } => {
|
||||||
read_dir(&config, package_info, path, options).map(Into::into)
|
read_dir(&config, package_info, env, path, options).map(Into::into)
|
||||||
}
|
}
|
||||||
#[cfg(not(fs_read_dir))]
|
#[cfg(not(fs_read_dir))]
|
||||||
Self::ReadDir { .. } => Err(crate::Error::ApiNotAllowlisted("fs > readDir".to_string())),
|
Self::ReadDir { .. } => Err(crate::Error::ApiNotAllowlisted("fs > readDir".to_string())),
|
||||||
@ -155,13 +157,13 @@ impl Cmd {
|
|||||||
source,
|
source,
|
||||||
destination,
|
destination,
|
||||||
options,
|
options,
|
||||||
} => copy_file(&config, package_info, source, destination, options).map(Into::into),
|
} => copy_file(&config, package_info, env, source, destination, options).map(Into::into),
|
||||||
#[cfg(not(fs_copy_file))]
|
#[cfg(not(fs_copy_file))]
|
||||||
Self::CopyFile { .. } => Err(crate::Error::ApiNotAllowlisted("fs > copyFile".to_string())),
|
Self::CopyFile { .. } => Err(crate::Error::ApiNotAllowlisted("fs > copyFile".to_string())),
|
||||||
|
|
||||||
#[cfg(fs_create_dir)]
|
#[cfg(fs_create_dir)]
|
||||||
Self::CreateDir { path, options } => {
|
Self::CreateDir { path, options } => {
|
||||||
create_dir(&config, package_info, path, options).map(Into::into)
|
create_dir(&config, package_info, env, path, options).map(Into::into)
|
||||||
}
|
}
|
||||||
#[cfg(not(fs_create_dir))]
|
#[cfg(not(fs_create_dir))]
|
||||||
Self::CreateDir { .. } => Err(crate::Error::ApiNotAllowlisted(
|
Self::CreateDir { .. } => Err(crate::Error::ApiNotAllowlisted(
|
||||||
@ -170,7 +172,7 @@ impl Cmd {
|
|||||||
|
|
||||||
#[cfg(fs_remove_dir)]
|
#[cfg(fs_remove_dir)]
|
||||||
Self::RemoveDir { path, options } => {
|
Self::RemoveDir { path, options } => {
|
||||||
remove_dir(&config, package_info, path, options).map(Into::into)
|
remove_dir(&config, package_info, env, path, options).map(Into::into)
|
||||||
}
|
}
|
||||||
#[cfg(not(fs_remove_dir))]
|
#[cfg(not(fs_remove_dir))]
|
||||||
Self::RemoveDir { .. } => Err(crate::Error::ApiNotAllowlisted(
|
Self::RemoveDir { .. } => Err(crate::Error::ApiNotAllowlisted(
|
||||||
@ -179,7 +181,7 @@ impl Cmd {
|
|||||||
|
|
||||||
#[cfg(fs_remove_file)]
|
#[cfg(fs_remove_file)]
|
||||||
Self::RemoveFile { path, options } => {
|
Self::RemoveFile { path, options } => {
|
||||||
remove_file(&config, package_info, path, options).map(Into::into)
|
remove_file(&config, package_info, env, path, options).map(Into::into)
|
||||||
}
|
}
|
||||||
#[cfg(not(fs_remove_file))]
|
#[cfg(not(fs_remove_file))]
|
||||||
Self::RemoveFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
Self::RemoveFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
||||||
@ -191,7 +193,7 @@ impl Cmd {
|
|||||||
old_path,
|
old_path,
|
||||||
new_path,
|
new_path,
|
||||||
options,
|
options,
|
||||||
} => rename_file(&config, package_info, old_path, new_path, options).map(Into::into),
|
} => rename_file(&config, package_info, env, old_path, new_path, options).map(Into::into),
|
||||||
#[cfg(not(fs_rename_file))]
|
#[cfg(not(fs_rename_file))]
|
||||||
Self::RenameFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
Self::RenameFile { .. } => Err(crate::Error::ApiNotAllowlisted(
|
||||||
"fs > renameFile".to_string(),
|
"fs > renameFile".to_string(),
|
||||||
@ -205,6 +207,7 @@ impl Cmd {
|
|||||||
pub fn read_dir(
|
pub fn read_dir(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
options: Option<DirOperationOptions>,
|
options: Option<DirOperationOptions>,
|
||||||
) -> crate::Result<Vec<dir::DiskEntry>> {
|
) -> crate::Result<Vec<dir::DiskEntry>> {
|
||||||
@ -213,8 +216,11 @@ pub fn read_dir(
|
|||||||
} else {
|
} else {
|
||||||
(false, None)
|
(false, None)
|
||||||
};
|
};
|
||||||
dir::read_dir(resolve_path(config, package_info, path, dir)?, recursive)
|
dir::read_dir(
|
||||||
.map_err(crate::Error::FailedToExecuteApi)
|
resolve_path(config, package_info, env, path, dir)?,
|
||||||
|
recursive,
|
||||||
|
)
|
||||||
|
.map_err(crate::Error::FailedToExecuteApi)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copies a file.
|
/// Copies a file.
|
||||||
@ -222,14 +228,15 @@ pub fn read_dir(
|
|||||||
pub fn copy_file(
|
pub fn copy_file(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
source: PathBuf,
|
source: PathBuf,
|
||||||
destination: PathBuf,
|
destination: PathBuf,
|
||||||
options: Option<FileOperationOptions>,
|
options: Option<FileOperationOptions>,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let (src, dest) = match options.and_then(|o| o.dir) {
|
let (src, dest) = match options.and_then(|o| o.dir) {
|
||||||
Some(dir) => (
|
Some(dir) => (
|
||||||
resolve_path(config, package_info, source, Some(dir.clone()))?,
|
resolve_path(config, package_info, env, source, Some(dir.clone()))?,
|
||||||
resolve_path(config, package_info, destination, Some(dir))?,
|
resolve_path(config, package_info, env, destination, Some(dir))?,
|
||||||
),
|
),
|
||||||
None => (source, destination),
|
None => (source, destination),
|
||||||
};
|
};
|
||||||
@ -242,6 +249,7 @@ pub fn copy_file(
|
|||||||
pub fn create_dir(
|
pub fn create_dir(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
options: Option<DirOperationOptions>,
|
options: Option<DirOperationOptions>,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
@ -250,7 +258,7 @@ pub fn create_dir(
|
|||||||
} else {
|
} else {
|
||||||
(false, None)
|
(false, None)
|
||||||
};
|
};
|
||||||
let resolved_path = resolve_path(config, package_info, path, dir)?;
|
let resolved_path = resolve_path(config, package_info, env, path, dir)?;
|
||||||
if recursive {
|
if recursive {
|
||||||
fs::create_dir_all(resolved_path)?;
|
fs::create_dir_all(resolved_path)?;
|
||||||
} else {
|
} else {
|
||||||
@ -265,6 +273,7 @@ pub fn create_dir(
|
|||||||
pub fn remove_dir(
|
pub fn remove_dir(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
options: Option<DirOperationOptions>,
|
options: Option<DirOperationOptions>,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
@ -273,7 +282,7 @@ pub fn remove_dir(
|
|||||||
} else {
|
} else {
|
||||||
(false, None)
|
(false, None)
|
||||||
};
|
};
|
||||||
let resolved_path = resolve_path(config, package_info, path, dir)?;
|
let resolved_path = resolve_path(config, package_info, env, path, dir)?;
|
||||||
if recursive {
|
if recursive {
|
||||||
fs::remove_dir_all(resolved_path)?;
|
fs::remove_dir_all(resolved_path)?;
|
||||||
} else {
|
} else {
|
||||||
@ -288,10 +297,11 @@ pub fn remove_dir(
|
|||||||
pub fn remove_file(
|
pub fn remove_file(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
options: Option<FileOperationOptions>,
|
options: Option<FileOperationOptions>,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let resolved_path = resolve_path(config, package_info, path, options.and_then(|o| o.dir))?;
|
let resolved_path = resolve_path(config, package_info, env, path, options.and_then(|o| o.dir))?;
|
||||||
fs::remove_file(resolved_path)?;
|
fs::remove_file(resolved_path)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -301,14 +311,15 @@ pub fn remove_file(
|
|||||||
pub fn rename_file(
|
pub fn rename_file(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
old_path: PathBuf,
|
old_path: PathBuf,
|
||||||
new_path: PathBuf,
|
new_path: PathBuf,
|
||||||
options: Option<FileOperationOptions>,
|
options: Option<FileOperationOptions>,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let (old, new) = match options.and_then(|o| o.dir) {
|
let (old, new) = match options.and_then(|o| o.dir) {
|
||||||
Some(dir) => (
|
Some(dir) => (
|
||||||
resolve_path(config, package_info, old_path, Some(dir.clone()))?,
|
resolve_path(config, package_info, env, old_path, Some(dir.clone()))?,
|
||||||
resolve_path(config, package_info, new_path, Some(dir))?,
|
resolve_path(config, package_info, env, new_path, Some(dir))?,
|
||||||
),
|
),
|
||||||
None => (old_path, new_path),
|
None => (old_path, new_path),
|
||||||
};
|
};
|
||||||
@ -320,6 +331,7 @@ pub fn rename_file(
|
|||||||
pub fn write_file(
|
pub fn write_file(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
contents: String,
|
contents: String,
|
||||||
options: Option<FileOperationOptions>,
|
options: Option<FileOperationOptions>,
|
||||||
@ -327,6 +339,7 @@ pub fn write_file(
|
|||||||
File::create(resolve_path(
|
File::create(resolve_path(
|
||||||
config,
|
config,
|
||||||
package_info,
|
package_info,
|
||||||
|
env,
|
||||||
path,
|
path,
|
||||||
options.and_then(|o| o.dir),
|
options.and_then(|o| o.dir),
|
||||||
)?)
|
)?)
|
||||||
@ -340,6 +353,7 @@ pub fn write_file(
|
|||||||
pub fn write_binary_file(
|
pub fn write_binary_file(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
contents: String,
|
contents: String,
|
||||||
options: Option<FileOperationOptions>,
|
options: Option<FileOperationOptions>,
|
||||||
@ -350,6 +364,7 @@ pub fn write_binary_file(
|
|||||||
File::create(resolve_path(
|
File::create(resolve_path(
|
||||||
config,
|
config,
|
||||||
package_info,
|
package_info,
|
||||||
|
env,
|
||||||
path,
|
path,
|
||||||
options.and_then(|o| o.dir),
|
options.and_then(|o| o.dir),
|
||||||
)?)
|
)?)
|
||||||
@ -364,12 +379,14 @@ pub fn write_binary_file(
|
|||||||
pub fn read_text_file(
|
pub fn read_text_file(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
options: Option<FileOperationOptions>,
|
options: Option<FileOperationOptions>,
|
||||||
) -> crate::Result<String> {
|
) -> crate::Result<String> {
|
||||||
file::read_string(resolve_path(
|
file::read_string(resolve_path(
|
||||||
config,
|
config,
|
||||||
package_info,
|
package_info,
|
||||||
|
env,
|
||||||
path,
|
path,
|
||||||
options.and_then(|o| o.dir),
|
options.and_then(|o| o.dir),
|
||||||
)?)
|
)?)
|
||||||
@ -381,12 +398,14 @@ pub fn read_text_file(
|
|||||||
pub fn read_binary_file(
|
pub fn read_binary_file(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
options: Option<FileOperationOptions>,
|
options: Option<FileOperationOptions>,
|
||||||
) -> crate::Result<Vec<u8>> {
|
) -> crate::Result<Vec<u8>> {
|
||||||
file::read_binary(resolve_path(
|
file::read_binary(resolve_path(
|
||||||
config,
|
config,
|
||||||
package_info,
|
package_info,
|
||||||
|
env,
|
||||||
path,
|
path,
|
||||||
options.and_then(|o| o.dir),
|
options.and_then(|o| o.dir),
|
||||||
)?)
|
)?)
|
||||||
|
@ -6,7 +6,7 @@ use super::InvokeResponse;
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[cfg(notification_all)]
|
#[cfg(notification_all)]
|
||||||
use crate::api::notification::Notification;
|
use crate::{api::notification::Notification, Env, Manager};
|
||||||
use crate::{Config, PackageInfo, Runtime, Window};
|
use crate::{Config, PackageInfo, Runtime, Window};
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -55,7 +55,7 @@ impl Cmd {
|
|||||||
Self::Notification { .. } => Err(crate::Error::ApiNotAllowlisted("notification".to_string())),
|
Self::Notification { .. } => Err(crate::Error::ApiNotAllowlisted("notification".to_string())),
|
||||||
Self::IsNotificationPermissionGranted => {
|
Self::IsNotificationPermissionGranted => {
|
||||||
#[cfg(notification_all)]
|
#[cfg(notification_all)]
|
||||||
return is_permission_granted(&config, package_info).map(Into::into);
|
return is_permission_granted(&window, &config, package_info).map(Into::into);
|
||||||
#[cfg(not(notification_all))]
|
#[cfg(not(notification_all))]
|
||||||
Ok(false.into())
|
Ok(false.into())
|
||||||
}
|
}
|
||||||
@ -84,11 +84,13 @@ pub fn send(options: NotificationOptions, config: &Config) -> crate::Result<Invo
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(notification_all)]
|
#[cfg(notification_all)]
|
||||||
pub fn is_permission_granted(
|
pub fn is_permission_granted<R: Runtime>(
|
||||||
|
window: &Window<R>,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
) -> crate::Result<InvokeResponse> {
|
) -> crate::Result<InvokeResponse> {
|
||||||
let settings = crate::settings::read_settings(config, package_info);
|
let settings =
|
||||||
|
crate::settings::read_settings(config, package_info, window.state::<Env>().inner());
|
||||||
if let Some(allow_notification) = settings.allow_notification {
|
if let Some(allow_notification) = settings.allow_notification {
|
||||||
Ok(allow_notification.into())
|
Ok(allow_notification.into())
|
||||||
} else {
|
} else {
|
||||||
@ -102,7 +104,8 @@ pub fn request_permission<R: Runtime>(
|
|||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
) -> crate::Result<String> {
|
) -> crate::Result<String> {
|
||||||
let mut settings = crate::settings::read_settings(config, package_info);
|
let mut settings =
|
||||||
|
crate::settings::read_settings(config, package_info, window.state::<Env>().inner());
|
||||||
if let Some(allow_notification) = settings.allow_notification {
|
if let Some(allow_notification) = settings.allow_notification {
|
||||||
return Ok(if allow_notification {
|
return Ok(if allow_notification {
|
||||||
PERMISSION_GRANTED.to_string()
|
PERMISSION_GRANTED.to_string()
|
||||||
@ -123,7 +126,12 @@ pub fn request_permission<R: Runtime>(
|
|||||||
let answer = rx.recv().unwrap();
|
let answer = rx.recv().unwrap();
|
||||||
|
|
||||||
settings.allow_notification = Some(answer);
|
settings.allow_notification = Some(answer);
|
||||||
crate::settings::write_settings(config, package_info, settings)?;
|
crate::settings::write_settings(
|
||||||
|
config,
|
||||||
|
package_info,
|
||||||
|
window.state::<Env>().inner(),
|
||||||
|
settings,
|
||||||
|
)?;
|
||||||
|
|
||||||
if answer {
|
if answer {
|
||||||
Ok(PERMISSION_GRANTED.to_string())
|
Ok(PERMISSION_GRANTED.to_string())
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
use super::InvokeResponse;
|
use super::InvokeResponse;
|
||||||
use crate::{api::path::BaseDirectory, Config, PackageInfo};
|
use crate::{api::path::BaseDirectory, Config, PackageInfo, Runtime, Window};
|
||||||
|
#[cfg(path_all)]
|
||||||
|
use crate::{Env, Manager};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
#[cfg(path_all)]
|
#[cfg(path_all)]
|
||||||
use std::path::{Component, Path, PathBuf, MAIN_SEPARATOR};
|
use std::path::{Component, Path, PathBuf, MAIN_SEPARATOR};
|
||||||
@ -42,16 +44,22 @@ pub enum Cmd {
|
|||||||
|
|
||||||
impl Cmd {
|
impl Cmd {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub fn run(
|
pub fn run<R: Runtime>(
|
||||||
self,
|
self,
|
||||||
|
window: Window<R>,
|
||||||
config: Arc<Config>,
|
config: Arc<Config>,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
) -> crate::Result<InvokeResponse> {
|
) -> crate::Result<InvokeResponse> {
|
||||||
#[cfg(path_all)]
|
#[cfg(path_all)]
|
||||||
return match self {
|
return match self {
|
||||||
Cmd::ResolvePath { directory, path } => {
|
Cmd::ResolvePath { directory, path } => resolve_path_handler(
|
||||||
resolve_path_handler(&config, package_info, path, directory).map(Into::into)
|
&config,
|
||||||
}
|
package_info,
|
||||||
|
window.state::<Env>().inner(),
|
||||||
|
path,
|
||||||
|
directory,
|
||||||
|
)
|
||||||
|
.map(Into::into),
|
||||||
Cmd::Resolve { paths } => resolve(paths).map(Into::into),
|
Cmd::Resolve { paths } => resolve(paths).map(Into::into),
|
||||||
Cmd::Normalize { path } => normalize(path).map(Into::into),
|
Cmd::Normalize { path } => normalize(path).map(Into::into),
|
||||||
Cmd::Join { paths } => join(paths).map(Into::into),
|
Cmd::Join { paths } => join(paths).map(Into::into),
|
||||||
@ -69,10 +77,11 @@ impl Cmd {
|
|||||||
pub fn resolve_path_handler(
|
pub fn resolve_path_handler(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
path: String,
|
path: String,
|
||||||
directory: Option<BaseDirectory>,
|
directory: Option<BaseDirectory>,
|
||||||
) -> crate::Result<PathBuf> {
|
) -> crate::Result<PathBuf> {
|
||||||
crate::api::path::resolve_path(config, package_info, path, directory).map_err(Into::into)
|
crate::api::path::resolve_path(config, package_info, env, path, directory).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(path_all)]
|
#[cfg(path_all)]
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
use super::InvokeResponse;
|
use super::InvokeResponse;
|
||||||
use crate::api::process::restart;
|
use crate::{api::process::restart, Manager, Runtime, Window};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
/// The API descriptor.
|
/// The API descriptor.
|
||||||
@ -20,10 +20,10 @@ pub enum Cmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Cmd {
|
impl Cmd {
|
||||||
pub fn run(self) -> crate::Result<InvokeResponse> {
|
pub fn run<R: Runtime>(self, window: Window<R>) -> crate::Result<InvokeResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::Relaunch => Ok({
|
Self::Relaunch => Ok({
|
||||||
restart();
|
restart(&window.state());
|
||||||
().into()
|
().into()
|
||||||
}),
|
}),
|
||||||
Self::Exit { exit_code } => {
|
Self::Exit { exit_code } => {
|
||||||
|
@ -108,7 +108,7 @@ pub use {
|
|||||||
self::utils::{
|
self::utils::{
|
||||||
assets::Assets,
|
assets::Assets,
|
||||||
config::{Config, WindowUrl},
|
config::{Config, WindowUrl},
|
||||||
PackageInfo,
|
Env, PackageInfo,
|
||||||
},
|
},
|
||||||
self::window::{Monitor, Window},
|
self::window::{Monitor, Window},
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,7 @@ use crate::{
|
|||||||
file::read_binary,
|
file::read_binary,
|
||||||
path::{resolve_path, BaseDirectory},
|
path::{resolve_path, BaseDirectory},
|
||||||
},
|
},
|
||||||
Config, PackageInfo,
|
Config, Env, PackageInfo,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
@ -30,10 +30,15 @@ pub struct Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the path to the settings file.
|
/// Gets the path to the settings file.
|
||||||
fn get_settings_path(config: &Config, package_info: &PackageInfo) -> crate::api::Result<PathBuf> {
|
fn get_settings_path(
|
||||||
|
config: &Config,
|
||||||
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
|
) -> crate::api::Result<PathBuf> {
|
||||||
resolve_path(
|
resolve_path(
|
||||||
config,
|
config,
|
||||||
package_info,
|
package_info,
|
||||||
|
env,
|
||||||
".tauri-settings",
|
".tauri-settings",
|
||||||
Some(BaseDirectory::App),
|
Some(BaseDirectory::App),
|
||||||
)
|
)
|
||||||
@ -44,9 +49,10 @@ fn get_settings_path(config: &Config, package_info: &PackageInfo) -> crate::api:
|
|||||||
pub(crate) fn write_settings(
|
pub(crate) fn write_settings(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
package_info: &PackageInfo,
|
package_info: &PackageInfo,
|
||||||
|
env: &Env,
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let settings_path = get_settings_path(config, package_info)?;
|
let settings_path = get_settings_path(config, package_info, env)?;
|
||||||
let settings_folder = Path::new(&settings_path).parent().unwrap();
|
let settings_folder = Path::new(&settings_path).parent().unwrap();
|
||||||
if !settings_folder.exists() {
|
if !settings_folder.exists() {
|
||||||
std::fs::create_dir(settings_folder)?;
|
std::fs::create_dir(settings_folder)?;
|
||||||
@ -60,8 +66,8 @@ pub(crate) fn write_settings(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Reads the settings from the file system.
|
/// Reads the settings from the file system.
|
||||||
pub fn read_settings(config: &Config, package_info: &PackageInfo) -> Settings {
|
pub fn read_settings(config: &Config, package_info: &PackageInfo, env: &Env) -> Settings {
|
||||||
if let Ok(settings_path) = get_settings_path(config, package_info) {
|
if let Ok(settings_path) = get_settings_path(config, package_info, env) {
|
||||||
if settings_path.exists() {
|
if settings_path.exists() {
|
||||||
read_binary(settings_path)
|
read_binary(settings_path)
|
||||||
.and_then(|settings| bincode::deserialize(&settings).map_err(Into::into))
|
.and_then(|settings| bincode::deserialize(&settings).map_err(Into::into))
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
use super::error::{Error, Result};
|
use super::error::{Error, Result};
|
||||||
use crate::api::{file::Extract, version};
|
use crate::{
|
||||||
|
api::{file::Extract, version},
|
||||||
|
Env,
|
||||||
|
};
|
||||||
use base64::decode;
|
use base64::decode;
|
||||||
use http::StatusCode;
|
use http::StatusCode;
|
||||||
use minisign_verify::{PublicKey, Signature};
|
use minisign_verify::{PublicKey, Signature};
|
||||||
@ -171,6 +174,8 @@ impl RemoteRelease {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UpdateBuilder<'a> {
|
pub struct UpdateBuilder<'a> {
|
||||||
|
/// Environment information.
|
||||||
|
pub env: Env,
|
||||||
/// Current version we are running to compare with announced version
|
/// Current version we are running to compare with announced version
|
||||||
pub current_version: &'a str,
|
pub current_version: &'a str,
|
||||||
/// The URLs to checks updates. We suggest at least one fallback on a different domain.
|
/// The URLs to checks updates. We suggest at least one fallback on a different domain.
|
||||||
@ -181,22 +186,17 @@ pub struct UpdateBuilder<'a> {
|
|||||||
pub executable_path: Option<PathBuf>,
|
pub executable_path: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Default for UpdateBuilder<'a> {
|
// Create new updater instance and return an Update
|
||||||
fn default() -> Self {
|
impl<'a> UpdateBuilder<'a> {
|
||||||
|
pub fn new(env: Env) -> Self {
|
||||||
UpdateBuilder {
|
UpdateBuilder {
|
||||||
|
env,
|
||||||
urls: Vec::new(),
|
urls: Vec::new(),
|
||||||
target: None,
|
target: None,
|
||||||
executable_path: None,
|
executable_path: None,
|
||||||
current_version: env!("CARGO_PKG_VERSION"),
|
current_version: env!("CARGO_PKG_VERSION"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Create new updater instance and return an Update
|
|
||||||
impl<'a> UpdateBuilder<'a> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
UpdateBuilder::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn url(mut self, url: String) -> Self {
|
pub fn url(mut self, url: String) -> Self {
|
||||||
@ -267,7 +267,7 @@ impl<'a> UpdateBuilder<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Get the extract_path from the provided executable_path
|
// Get the extract_path from the provided executable_path
|
||||||
let extract_path = extract_path_from_executable(&executable_path);
|
let extract_path = extract_path_from_executable(&self.env, &executable_path);
|
||||||
|
|
||||||
// Set SSL certs for linux if they aren't available.
|
// Set SSL certs for linux if they aren't available.
|
||||||
// We do not require to recheck in the download_and_install as we use
|
// We do not require to recheck in the download_and_install as we use
|
||||||
@ -357,6 +357,7 @@ impl<'a> UpdateBuilder<'a> {
|
|||||||
|
|
||||||
// create our new updater
|
// create our new updater
|
||||||
Ok(Update {
|
Ok(Update {
|
||||||
|
env: self.env,
|
||||||
target,
|
target,
|
||||||
extract_path,
|
extract_path,
|
||||||
should_update,
|
should_update,
|
||||||
@ -372,12 +373,14 @@ impl<'a> UpdateBuilder<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn builder<'a>() -> UpdateBuilder<'a> {
|
pub fn builder<'a>(env: Env) -> UpdateBuilder<'a> {
|
||||||
UpdateBuilder::new()
|
UpdateBuilder::new(env)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Update {
|
pub struct Update {
|
||||||
|
/// Environment information.
|
||||||
|
pub env: Env,
|
||||||
/// Update description
|
/// Update description
|
||||||
pub body: Option<String>,
|
pub body: Option<String>,
|
||||||
/// Should we update or not
|
/// Should we update or not
|
||||||
@ -418,7 +421,7 @@ impl Update {
|
|||||||
// be set with our APPIMAGE env variable, we don't need to do
|
// be set with our APPIMAGE env variable, we don't need to do
|
||||||
// anythin with it yet
|
// anythin with it yet
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
if env::var_os("APPIMAGE").is_none() {
|
if self.env.appimage.is_none() {
|
||||||
return Err(Error::UnsupportedPlatform);
|
return Err(Error::UnsupportedPlatform);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -718,7 +721,7 @@ pub fn get_updater_target() -> Option<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the extract_path from the provided executable_path
|
/// Get the extract_path from the provided executable_path
|
||||||
pub fn extract_path_from_executable(executable_path: &Path) -> PathBuf {
|
pub fn extract_path_from_executable(env: &Env, executable_path: &Path) -> 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
|
||||||
@ -748,7 +751,7 @@ pub fn extract_path_from_executable(executable_path: &Path) -> PathBuf {
|
|||||||
// We should use APPIMAGE exposed env variable
|
// We should use APPIMAGE exposed env variable
|
||||||
// This is where our APPIMAGE should sit and should be replaced
|
// This is where our APPIMAGE should sit and should be replaced
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
if let Some(app_image_path) = env::var_os("APPIMAGE") {
|
if let Some(app_image_path) = &env.appimage {
|
||||||
return PathBuf::from(app_image_path);
|
return PathBuf::from(app_image_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,9 +908,10 @@ mod test {
|
|||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_app_name_in_path() {
|
fn test_app_name_in_path() {
|
||||||
let executable = extract_path_from_executable(Path::new(
|
let executable = extract_path_from_executable(
|
||||||
"/Applications/updater-example.app/Contents/MacOS/updater-example",
|
&crate::Env::default(),
|
||||||
));
|
Path::new("/Applications/updater-example.app/Contents/MacOS/updater-example"),
|
||||||
|
);
|
||||||
let app_name = macos_app_name_in_path(&executable);
|
let app_name = macos_app_name_in_path(&executable);
|
||||||
assert!(executable.ends_with("updater-example.app"));
|
assert!(executable.ends_with("updater-example.app"));
|
||||||
assert_eq!(app_name, "updater-example.app".to_string());
|
assert_eq!(app_name, "updater-example.app".to_string());
|
||||||
@ -921,7 +925,7 @@ mod test {
|
|||||||
.with_body(generate_sample_raw_json())
|
.with_body(generate_sample_raw_json())
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
let check_update = block!(builder()
|
let check_update = block!(builder(Default::default())
|
||||||
.current_version("0.0.0")
|
.current_version("0.0.0")
|
||||||
.url(mockito::server_url())
|
.url(mockito::server_url())
|
||||||
.build());
|
.build());
|
||||||
@ -940,7 +944,7 @@ mod test {
|
|||||||
.with_body(generate_sample_raw_json())
|
.with_body(generate_sample_raw_json())
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
let check_update = block!(builder()
|
let check_update = block!(builder(Default::default())
|
||||||
.current_version("0.0.0")
|
.current_version("0.0.0")
|
||||||
.url(mockito::server_url())
|
.url(mockito::server_url())
|
||||||
.build());
|
.build());
|
||||||
@ -959,7 +963,7 @@ mod test {
|
|||||||
.with_body(generate_sample_raw_json())
|
.with_body(generate_sample_raw_json())
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
let check_update = block!(builder()
|
let check_update = block!(builder(Default::default())
|
||||||
.current_version("0.0.0")
|
.current_version("0.0.0")
|
||||||
.target("win64")
|
.target("win64")
|
||||||
.url(mockito::server_url())
|
.url(mockito::server_url())
|
||||||
@ -985,7 +989,7 @@ mod test {
|
|||||||
.with_body(generate_sample_raw_json())
|
.with_body(generate_sample_raw_json())
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
let check_update = block!(builder()
|
let check_update = block!(builder(Default::default())
|
||||||
.current_version("10.0.0")
|
.current_version("10.0.0")
|
||||||
.url(mockito::server_url())
|
.url(mockito::server_url())
|
||||||
.build());
|
.build());
|
||||||
@ -1008,7 +1012,7 @@ mod test {
|
|||||||
))
|
))
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
let check_update = block!(builder()
|
let check_update = block!(builder(Default::default())
|
||||||
.current_version("1.0.0")
|
.current_version("1.0.0")
|
||||||
.url(format!(
|
.url(format!(
|
||||||
"{}/darwin/{{{{current_version}}}}",
|
"{}/darwin/{{{{current_version}}}}",
|
||||||
@ -1035,7 +1039,7 @@ mod test {
|
|||||||
))
|
))
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
let check_update = block!(builder()
|
let check_update = block!(builder(Default::default())
|
||||||
.current_version("1.0.0")
|
.current_version("1.0.0")
|
||||||
.url(format!(
|
.url(format!(
|
||||||
"{}/win64/{{{{current_version}}}}",
|
"{}/win64/{{{{current_version}}}}",
|
||||||
@ -1061,7 +1065,7 @@ mod test {
|
|||||||
))
|
))
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
let check_update = block!(builder()
|
let check_update = block!(builder(Default::default())
|
||||||
.current_version("10.0.0")
|
.current_version("10.0.0")
|
||||||
.url(format!(
|
.url(format!(
|
||||||
"{}/darwin/{{{{current_version}}}}",
|
"{}/darwin/{{{{current_version}}}}",
|
||||||
@ -1083,7 +1087,7 @@ mod test {
|
|||||||
.with_body(generate_sample_raw_json())
|
.with_body(generate_sample_raw_json())
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
let check_update = block!(builder()
|
let check_update = block!(builder(Default::default())
|
||||||
.url("http://badurl.www.tld/1".into())
|
.url("http://badurl.www.tld/1".into())
|
||||||
.url(mockito::server_url())
|
.url(mockito::server_url())
|
||||||
.current_version("0.0.1")
|
.current_version("0.0.1")
|
||||||
@ -1103,7 +1107,7 @@ mod test {
|
|||||||
.with_body(generate_sample_raw_json())
|
.with_body(generate_sample_raw_json())
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
let check_update = block!(builder()
|
let check_update = block!(builder(Default::default())
|
||||||
.urls(&["http://badurl.www.tld/1".into(), mockito::server_url(),])
|
.urls(&["http://badurl.www.tld/1".into(), mockito::server_url(),])
|
||||||
.current_version("0.0.1")
|
.current_version("0.0.1")
|
||||||
.build());
|
.build());
|
||||||
@ -1122,7 +1126,7 @@ mod test {
|
|||||||
.with_body(generate_sample_bad_json())
|
.with_body(generate_sample_bad_json())
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
let check_update = block!(builder()
|
let check_update = block!(builder(Default::default())
|
||||||
.url(mockito::server_url())
|
.url(mockito::server_url())
|
||||||
.current_version("0.0.1")
|
.current_version("0.0.1")
|
||||||
.build());
|
.build());
|
||||||
@ -1186,7 +1190,7 @@ mod test {
|
|||||||
let tmp_dir_path = tmp_dir_unwrap.path();
|
let tmp_dir_path = tmp_dir_unwrap.path();
|
||||||
|
|
||||||
// configure the updater
|
// configure the updater
|
||||||
let check_update = block!(builder()
|
let check_update = block!(builder(Default::default())
|
||||||
.url(mockito::server_url())
|
.url(mockito::server_url())
|
||||||
// It should represent the executable path, that's why we add my_app.exe in our
|
// It should represent the executable path, that's why we add my_app.exe in our
|
||||||
// test path -- in production you shouldn't have to provide it
|
// test path -- in production you shouldn't have to provide it
|
||||||
|
@ -336,7 +336,7 @@ use crate::{
|
|||||||
api::{dialog::ask, process::restart},
|
api::{dialog::ask, process::restart},
|
||||||
runtime::Runtime,
|
runtime::Runtime,
|
||||||
utils::config::UpdaterConfig,
|
utils::config::UpdaterConfig,
|
||||||
Window,
|
Env, Manager, Window,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
@ -381,8 +381,9 @@ pub(crate) async fn check_update_with_dialog<R: Runtime>(
|
|||||||
window: Window<R>,
|
window: Window<R>,
|
||||||
) {
|
) {
|
||||||
if let Some(endpoints) = updater_config.endpoints.clone() {
|
if let Some(endpoints) = updater_config.endpoints.clone() {
|
||||||
|
let env = window.state::<Env>().inner().clone();
|
||||||
// check updates
|
// check updates
|
||||||
match self::core::builder()
|
match self::core::builder(env)
|
||||||
.urls(&endpoints[..])
|
.urls(&endpoints[..])
|
||||||
.current_version(&package_info.version)
|
.current_version(&package_info.version)
|
||||||
.build()
|
.build()
|
||||||
@ -448,8 +449,9 @@ pub(crate) fn listener<R: Runtime>(
|
|||||||
let window = window.clone();
|
let window = window.clone();
|
||||||
let window_isolation = window.clone();
|
let window_isolation = window.clone();
|
||||||
let pubkey = pubkey.clone();
|
let pubkey = pubkey.clone();
|
||||||
|
let env = window.state::<Env>().inner().clone();
|
||||||
|
|
||||||
match self::core::builder()
|
match self::core::builder(env)
|
||||||
.urls(&endpoints[..])
|
.urls(&endpoints[..])
|
||||||
.current_version(&package_info.version)
|
.current_version(&package_info.version)
|
||||||
.build()
|
.build()
|
||||||
@ -558,13 +560,14 @@ Release Notes:
|
|||||||
updater.download_and_install(pubkey.clone()).await?;
|
updater.download_and_install(pubkey.clone()).await?;
|
||||||
|
|
||||||
// Ask user if we need to restart the application
|
// Ask user if we need to restart the application
|
||||||
|
let env = window.state::<Env>().inner().clone();
|
||||||
ask(
|
ask(
|
||||||
Some(&window),
|
Some(&window),
|
||||||
"Ready to Restart",
|
"Ready to Restart",
|
||||||
"The installation was successful, do you want to restart the application now?",
|
"The installation was successful, do you want to restart the application now?",
|
||||||
|should_exit| {
|
move |should_exit| {
|
||||||
if should_exit {
|
if should_exit {
|
||||||
restart();
|
restart(&env);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#[cfg(not(any(feature = "api-all", feature = "shell-all", feature = "shell-execute")))]
|
#[cfg(not(any(feature = "api-all", feature = "shell-all", feature = "shell-execute")))]
|
||||||
fn main() {
|
fn main() {
|
||||||
eprintln!("Not supported without `api-all`, `shell-all` or `shell-execute`")
|
eprintln!("Not supported without `api-all`, `shell-all` and `shell-execute`")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "api-all", feature = "shell-all", feature = "shell-execute"))]
|
#[cfg(any(feature = "api-all", feature = "shell-all", feature = "shell-execute"))]
|
||||||
@ -25,6 +25,7 @@ fn main() {
|
|||||||
let script_path = resolve_path(
|
let script_path = resolve_path(
|
||||||
context.config(),
|
context.config(),
|
||||||
context.package_info(),
|
context.package_info(),
|
||||||
|
&Default::default(),
|
||||||
"assets/index.js",
|
"assets/index.js",
|
||||||
Some(BaseDirectory::Resource),
|
Some(BaseDirectory::Resource),
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user