mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-11-24 12:14:05 +03:00
feat(bundler) appimage (#37)
* add basic setup * add basic download logic * build test * add yaml parser. * finish appimage * cleanup and comment * add comment * modify chmod * fix line endings. * remove "cat runtime" * match desktop files * add path utils * add opts * add fileopts and diropts * create, create all and remove * copy file function * add copy logic and new error * add target to gitignore * refactor deb::bundle_project * finish refactor
This commit is contained in:
parent
70ccd1659d
commit
52e20d2544
7
.gitignore
vendored
7
.gitignore
vendored
@ -60,7 +60,14 @@ debug.log
|
|||||||
package-lock.json
|
package-lock.json
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
|
|
||||||
|
# Quasar output
|
||||||
|
bundle.json
|
||||||
|
config.json
|
||||||
|
|
||||||
|
# rust compiled folders
|
||||||
|
target
|
||||||
|
|
||||||
src-tauri
|
src-tauri
|
||||||
test/jest/tmp
|
test/jest/tmp
|
||||||
/tauri.conf.js
|
/tauri.conf.js
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ image = "0.12"
|
|||||||
libflate = "0.1"
|
libflate = "0.1"
|
||||||
md5 = "0.3"
|
md5 = "0.3"
|
||||||
msi = "0.2"
|
msi = "0.2"
|
||||||
|
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
strsim = "0.7"
|
strsim = "0.7"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
mod appimage_bundle;
|
||||||
mod category;
|
mod category;
|
||||||
mod common;
|
mod common;
|
||||||
mod deb_bundle;
|
mod deb_bundle;
|
||||||
@ -7,6 +8,7 @@ mod msi_bundle;
|
|||||||
mod osx_bundle;
|
mod osx_bundle;
|
||||||
mod rpm_bundle;
|
mod rpm_bundle;
|
||||||
mod settings;
|
mod settings;
|
||||||
|
mod path_utils;
|
||||||
mod wix;
|
mod wix;
|
||||||
|
|
||||||
pub use self::common::{print_error, print_finished};
|
pub use self::common::{print_error, print_finished};
|
||||||
@ -22,8 +24,11 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<PathBuf>> {
|
|||||||
// use dmg bundler
|
// use dmg bundler
|
||||||
// PackageType::OsxBundle => dmg_bundle::bundle_project(&settings)?,
|
// PackageType::OsxBundle => dmg_bundle::bundle_project(&settings)?,
|
||||||
PackageType::WindowsMsi => msi_bundle::bundle_project(&settings)?,
|
PackageType::WindowsMsi => msi_bundle::bundle_project(&settings)?,
|
||||||
|
// force appimage on linux
|
||||||
|
// PackageType::Deb => appimage_bundle::bundle_project(&settings)?,
|
||||||
PackageType::Deb => deb_bundle::bundle_project(&settings)?,
|
PackageType::Deb => deb_bundle::bundle_project(&settings)?,
|
||||||
PackageType::Rpm => rpm_bundle::bundle_project(&settings)?,
|
PackageType::Rpm => rpm_bundle::bundle_project(&settings)?,
|
||||||
|
PackageType::AppImage => appimage_bundle::bundle_project(&settings)?,
|
||||||
PackageType::Dmg => dmg_bundle::bundle_project(&settings)?,
|
PackageType::Dmg => dmg_bundle::bundle_project(&settings)?,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
100
tools/rust/cargo-tauri-bundle/src/bundle/appimage_bundle.rs
Normal file
100
tools/rust/cargo-tauri-bundle/src/bundle/appimage_bundle.rs
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
use super::common;
|
||||||
|
use super::deb_bundle;
|
||||||
|
use crate::Settings;
|
||||||
|
use super::path_utils;
|
||||||
|
|
||||||
|
use handlebars::Handlebars;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use std::fs::write;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
|
// Create handlebars template for shell script
|
||||||
|
lazy_static! {
|
||||||
|
static ref HANDLEBARS: Handlebars = {
|
||||||
|
let mut handlebars = Handlebars::new();
|
||||||
|
|
||||||
|
handlebars
|
||||||
|
.register_template_string("appimage", include_str!("templates/appimage"))
|
||||||
|
.unwrap();
|
||||||
|
handlebars
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// bundle the project.
|
||||||
|
pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
|
||||||
|
// generate the deb binary name
|
||||||
|
let arch = match settings.binary_arch() {
|
||||||
|
"x86" => "i386",
|
||||||
|
"x86_64" => "amd64",
|
||||||
|
other => other,
|
||||||
|
};
|
||||||
|
let package_base_name = format!(
|
||||||
|
"{}_{}_{}",
|
||||||
|
settings.binary_name(),
|
||||||
|
settings.version_string(),
|
||||||
|
arch
|
||||||
|
);
|
||||||
|
let base_dir = settings.project_out_directory().join("bundle/deb");
|
||||||
|
let package_dir = base_dir.join(&package_base_name);
|
||||||
|
if package_dir.exists() {
|
||||||
|
fs::remove_dir_all(&package_dir)
|
||||||
|
.chain_err(|| format!("Failed to remove old {}", package_base_name))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate deb_folder structure
|
||||||
|
deb_bundle::generate_folders(settings, &package_dir)?;
|
||||||
|
|
||||||
|
let app_dir_path = path_utils::create(
|
||||||
|
settings
|
||||||
|
.project_out_directory()
|
||||||
|
.join(format!("{}.AppDir", settings.binary_name())), true
|
||||||
|
);
|
||||||
|
|
||||||
|
let upcase = settings.binary_name().to_uppercase();
|
||||||
|
|
||||||
|
// setup data to insert into shell script
|
||||||
|
let mut sh_map = BTreeMap::new();
|
||||||
|
sh_map.insert("app_name", settings.binary_name());
|
||||||
|
sh_map.insert("bundle_name", package_base_name.as_str());
|
||||||
|
sh_map.insert("app_name_uppercase", upcase.as_str());
|
||||||
|
|
||||||
|
// initialize shell script template.
|
||||||
|
let temp = HANDLEBARS
|
||||||
|
.render("appimage", &sh_map)
|
||||||
|
.or_else(|e| Err(e.to_string()))?;
|
||||||
|
let output_path = settings.project_out_directory();
|
||||||
|
|
||||||
|
// create the shell script file in the target/ folder.
|
||||||
|
let sh_file = output_path.join("build_appimage");
|
||||||
|
common::print_bundling(
|
||||||
|
format!(
|
||||||
|
"{:?}",
|
||||||
|
&output_path.join(format!("{}.AppImage", settings.binary_name()))
|
||||||
|
)
|
||||||
|
.as_str(),
|
||||||
|
)?;
|
||||||
|
write(&sh_file, temp).or_else(|e| Err(e.to_string()))?;
|
||||||
|
|
||||||
|
// chmod script for execution
|
||||||
|
Command::new("chmod")
|
||||||
|
.arg("777")
|
||||||
|
.arg(&sh_file)
|
||||||
|
.current_dir(output_path)
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.expect("Failed to chmod script");
|
||||||
|
|
||||||
|
// execute the shell script to build the appimage.
|
||||||
|
Command::new(&sh_file)
|
||||||
|
.current_dir(output_path)
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.expect("Failed to execute shell script");
|
||||||
|
|
||||||
|
Ok(vec![sh_file])
|
||||||
|
}
|
@ -56,15 +56,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
|
|||||||
}
|
}
|
||||||
let package_path = base_dir.join(package_name);
|
let package_path = base_dir.join(package_name);
|
||||||
|
|
||||||
// Generate data files.
|
let data_dir = generate_folders(settings, &package_dir).chain_err(|| "Failed to build folders")?;
|
||||||
let data_dir = package_dir.join("data");
|
|
||||||
let binary_dest = data_dir.join("usr/bin").join(settings.binary_name());
|
|
||||||
common::copy_file(settings.binary_path(), &binary_dest)
|
|
||||||
.chain_err(|| "Failed to copy binary file")?;
|
|
||||||
transfer_resource_files(settings, &data_dir).chain_err(|| "Failed to copy resource files")?;
|
|
||||||
generate_icon_files(settings, &data_dir).chain_err(|| "Failed to create icon files")?;
|
|
||||||
generate_desktop_file(settings, &data_dir).chain_err(|| "Failed to create desktop file")?;
|
|
||||||
|
|
||||||
// Generate control files.
|
// Generate control files.
|
||||||
let control_dir = package_dir.join("control");
|
let control_dir = package_dir.join("control");
|
||||||
generate_control_file(settings, arch, &control_dir, &data_dir)
|
generate_control_file(settings, arch, &control_dir, &data_dir)
|
||||||
@ -90,6 +82,20 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
|
|||||||
Ok(vec![package_path])
|
Ok(vec![package_path])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate_folders(settings: &Settings, package_dir: &Path) -> crate::Result<PathBuf> {
|
||||||
|
|
||||||
|
// Generate data files.
|
||||||
|
let data_dir = package_dir.join("data");
|
||||||
|
let binary_dest = data_dir.join("usr/bin").join(settings.binary_name());
|
||||||
|
common::copy_file(settings.binary_path(), &binary_dest)
|
||||||
|
.chain_err(|| "Failed to copy binary file")?;
|
||||||
|
transfer_resource_files(settings, &data_dir).chain_err(|| "Failed to copy resource files")?;
|
||||||
|
generate_icon_files(settings, &data_dir).chain_err(|| "Failed to create icon files")?;
|
||||||
|
generate_desktop_file(settings, &data_dir).chain_err(|| "Failed to create desktop file")?;
|
||||||
|
|
||||||
|
Ok(data_dir)
|
||||||
|
}
|
||||||
|
|
||||||
/// Generate the application desktop file and store it under the `data_dir`.
|
/// Generate the application desktop file and store it under the `data_dir`.
|
||||||
fn generate_desktop_file(settings: &Settings, data_dir: &Path) -> crate::Result<()> {
|
fn generate_desktop_file(settings: &Settings, data_dir: &Path) -> crate::Result<()> {
|
||||||
let bin_name = settings.binary_name();
|
let bin_name = settings.binary_name();
|
||||||
|
256
tools/rust/cargo-tauri-bundle/src/bundle/path_utils.rs
Normal file
256
tools/rust/cargo-tauri-bundle/src/bundle/path_utils.rs
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
use std::fs::{create_dir, create_dir_all, read_dir, remove_dir_all};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct DirOpts {
|
||||||
|
pub depth: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FileOpts {
|
||||||
|
pub overwrite: bool,
|
||||||
|
pub skip: bool,
|
||||||
|
pub buffer_size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Options {
|
||||||
|
pub overwrite: bool,
|
||||||
|
pub skip: bool,
|
||||||
|
pub buffer_size: usize,
|
||||||
|
pub copy_files: bool,
|
||||||
|
pub content_only: bool,
|
||||||
|
pub depth: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DirInfo {
|
||||||
|
pub size: u64,
|
||||||
|
pub files: Vec<String>,
|
||||||
|
pub directories: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Options {
|
||||||
|
pub fn new() -> Options {
|
||||||
|
Options {
|
||||||
|
overwrite: false,
|
||||||
|
skip: false,
|
||||||
|
buffer_size: 64000,
|
||||||
|
copy_files: false,
|
||||||
|
content_only: false,
|
||||||
|
depth: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DirOpts {
|
||||||
|
pub fn new() -> DirOpts {
|
||||||
|
DirOpts { depth: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileOpts {
|
||||||
|
pub fn new() -> FileOpts {
|
||||||
|
FileOpts {
|
||||||
|
overwrite: false,
|
||||||
|
skip: false,
|
||||||
|
buffer_size: 64000,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create<P>(path: P, erase: bool) -> crate::Result<()>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
if erase && path.as_ref().exists() {
|
||||||
|
remove(&path)?;
|
||||||
|
}
|
||||||
|
Ok(create_dir(&path)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_all<P>(path: P, erase: bool) -> crate::Result<()>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
if erase && path.as_ref().exists() {
|
||||||
|
remove(&path)?;
|
||||||
|
}
|
||||||
|
Ok(create_dir_all(&path)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove<P: AsRef<Path>>(path: P) -> crate::Result<()> {
|
||||||
|
if path.as_ref().exists() {
|
||||||
|
Ok(remove_dir_all(path)?)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy_file<P, Q>(from: P, to: Q, options: &FileOpts) -> crate::Result<u64>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
Q: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let from = from.as_ref();
|
||||||
|
if !from.exists() {
|
||||||
|
if let Some(msg) = from.to_str() {
|
||||||
|
let msg = format!("Path \"{}\" does not exist or you don't have access", msg);
|
||||||
|
return Err(msg.into());
|
||||||
|
}
|
||||||
|
return Err("Path does not exist Or you don't have access!".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if !from.is_file() {
|
||||||
|
if let Some(msg) = from.to_str() {
|
||||||
|
let msg = format!("Path \"{}\" is not a file!", msg);
|
||||||
|
return Err(msg.into());
|
||||||
|
}
|
||||||
|
return Err("Path is not a file!".into());
|
||||||
|
}
|
||||||
|
if !options.overwrite && to.as_ref().exists() {
|
||||||
|
if options.skip {
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(msg) = to.as_ref().to_str() {
|
||||||
|
let msg = format!("Path \"{}\" is exist", msg);
|
||||||
|
return Err(msg.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(std::fs::copy(from, to)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy<P, Q>(from: P, to: Q, options: &Options) -> crate::Result<u64>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
Q: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let from = from.as_ref();
|
||||||
|
if !from.exists() {
|
||||||
|
if let Some(msg) = from.to_str() {
|
||||||
|
let msg = format!("Path \"{}\" does not exist or you don't have access!", msg);
|
||||||
|
return Err(msg.into());
|
||||||
|
}
|
||||||
|
return Err("Path does not exist Or you don't have access!".into());
|
||||||
|
}
|
||||||
|
if !from.is_dir() {
|
||||||
|
if let Some(msg) = from.to_str() {
|
||||||
|
let msg = format!("Path \"{}\" is not a directory!", msg);
|
||||||
|
return Err(msg.into());
|
||||||
|
}
|
||||||
|
return Err("Path is not a directory!".into());
|
||||||
|
}
|
||||||
|
let dir_name;
|
||||||
|
if let Some(val) = from.components().last() {
|
||||||
|
dir_name = val.as_os_str();
|
||||||
|
} else {
|
||||||
|
return Err("Invalid folder from".into());
|
||||||
|
}
|
||||||
|
let mut to: PathBuf = to.as_ref().to_path_buf();
|
||||||
|
if !options.content_only && ((options.copy_files && to.exists()) || !options.copy_files) {
|
||||||
|
to.push(dir_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut read_options = DirOpts::new();
|
||||||
|
if options.depth > 0 {
|
||||||
|
read_options.depth = options.depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
let dir_content = get_dir_info(from, &read_options)?;
|
||||||
|
for directory in dir_content.directories {
|
||||||
|
let tmp_to = Path::new(&directory).strip_prefix(from)?;
|
||||||
|
let dir = to.join(&tmp_to);
|
||||||
|
if !dir.exists() {
|
||||||
|
if options.copy_files {
|
||||||
|
create_all(dir, false)?;
|
||||||
|
} else {
|
||||||
|
create(dir, false)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut result: u64 = 0;
|
||||||
|
for file in dir_content.files {
|
||||||
|
let to = to.to_path_buf();
|
||||||
|
let tp = Path::new(&file).strip_prefix(from)?;
|
||||||
|
let path = to.join(&tp);
|
||||||
|
|
||||||
|
let file_options = FileOpts {
|
||||||
|
overwrite: options.overwrite,
|
||||||
|
skip: options.skip,
|
||||||
|
buffer_size: options.buffer_size,
|
||||||
|
};
|
||||||
|
let mut result_copy: crate::Result<u64>;
|
||||||
|
let mut work = true;
|
||||||
|
|
||||||
|
while work {
|
||||||
|
result_copy = copy_file(&file, &path, &file_options);
|
||||||
|
match result_copy {
|
||||||
|
Ok(val) => {
|
||||||
|
result += val;
|
||||||
|
work = false;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
let err_msg = err.to_string();
|
||||||
|
return Err(err_msg.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_dir_info<P>(path: P, options: &DirOpts) -> crate::Result<DirInfo>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let mut depth = 0;
|
||||||
|
if options.depth != 0 {
|
||||||
|
depth = options.depth + 1;
|
||||||
|
}
|
||||||
|
_get_dir_info(path, depth)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _get_dir_info<P>(path: P, mut depth: u64) -> crate::Result<DirInfo>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let mut directories = Vec::new();
|
||||||
|
let mut files = Vec::new();
|
||||||
|
let mut size = 0;
|
||||||
|
let item = path.as_ref().to_str();
|
||||||
|
if !item.is_some() {
|
||||||
|
return Err("Invalid path".into());
|
||||||
|
}
|
||||||
|
let item = item.unwrap().to_string();
|
||||||
|
|
||||||
|
if path.as_ref().is_dir() {
|
||||||
|
directories.push(item);
|
||||||
|
if depth == 0 || depth > 1 {
|
||||||
|
if depth > 1 {
|
||||||
|
depth -= 1;
|
||||||
|
}
|
||||||
|
for entry in read_dir(&path)? {
|
||||||
|
let _path = entry?.path();
|
||||||
|
|
||||||
|
match _get_dir_info(_path, depth) {
|
||||||
|
Ok(items) => {
|
||||||
|
let mut _files = items.files;
|
||||||
|
let mut _dirrectories = items.directories;
|
||||||
|
size += items.size;
|
||||||
|
files.append(&mut _files);
|
||||||
|
directories.append(&mut _dirrectories);
|
||||||
|
}
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
size = path.as_ref().metadata()?.len();
|
||||||
|
files.push(item);
|
||||||
|
}
|
||||||
|
Ok(DirInfo {
|
||||||
|
size: size,
|
||||||
|
files: files,
|
||||||
|
directories: directories,
|
||||||
|
})
|
||||||
|
}
|
@ -17,6 +17,7 @@ pub enum PackageType {
|
|||||||
WindowsMsi,
|
WindowsMsi,
|
||||||
Deb,
|
Deb,
|
||||||
Rpm,
|
Rpm,
|
||||||
|
AppImage,
|
||||||
Dmg,
|
Dmg,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ impl PackageType {
|
|||||||
"msi" => Some(PackageType::WindowsMsi),
|
"msi" => Some(PackageType::WindowsMsi),
|
||||||
"osx" => Some(PackageType::OsxBundle),
|
"osx" => Some(PackageType::OsxBundle),
|
||||||
"rpm" => Some(PackageType::Rpm),
|
"rpm" => Some(PackageType::Rpm),
|
||||||
|
"appimage" => Some(PackageType::AppImage),
|
||||||
"dmg" => Some(PackageType::Dmg),
|
"dmg" => Some(PackageType::Dmg),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@ -41,6 +43,7 @@ impl PackageType {
|
|||||||
PackageType::WindowsMsi => "msi",
|
PackageType::WindowsMsi => "msi",
|
||||||
PackageType::OsxBundle => "osx",
|
PackageType::OsxBundle => "osx",
|
||||||
PackageType::Rpm => "rpm",
|
PackageType::Rpm => "rpm",
|
||||||
|
PackageType::AppImage => "appimage",
|
||||||
PackageType::Dmg => "dmg",
|
PackageType::Dmg => "dmg",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
tools/rust/cargo-tauri-bundle/src/bundle/templates/appimage
Normal file
28
tools/rust/cargo-tauri-bundle/src/bundle/templates/appimage
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
mkdir -p {{app_name}}.AppDir
|
||||||
|
cp -r bundle/deb/{{bundle_name}}/data/usr {{app_name}}.AppDir
|
||||||
|
cp {{app_name}} {{app_name}}.AppDir/AppRun
|
||||||
|
|
||||||
|
cd {{app_name}}.AppDir
|
||||||
|
|
||||||
|
cp usr/share/icons/hicolor/256x265/apps/{{app_name}}.png {{app_name}}.png
|
||||||
|
|
||||||
|
echo '[Desktop Entry]' > {{app_name}}.desktop
|
||||||
|
echo 'Version=1.0' >> {{app_name}}.desktop
|
||||||
|
echo 'Comment=A Tauri App' >> {{app_name}}.desktop
|
||||||
|
echo 'Exec={{app_name}}' >> {{app_name}}.desktop
|
||||||
|
echo 'Icon={{app_name}}' >> {{app_name}}.desktop
|
||||||
|
echo 'Name={{app_name_uppercase}}' >> {{app_name}}.desktop
|
||||||
|
echo 'Terminal=false' >> {{app_name}}.desktop
|
||||||
|
echo 'Type=Application' >> {{app_name}}.desktop
|
||||||
|
echo 'Categories=X-Web;' >> {{app_name}}.desktop
|
||||||
|
|
||||||
|
cp {{app_name}}.desktop {{app_name}}.AppDir/usr/share/applications/{{app_name}}.desktop
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
mksquashfs {{app_name}}.AppDir {{app_name}}.squashfs -root-owned -noappend
|
||||||
|
# cat runtime >> {{app_name}}.AppImage
|
||||||
|
cat {{app_name}}.squashfs >> {{app_name}}.AppImage
|
||||||
|
chmod a+x {{app_name}}.AppImage
|
@ -27,8 +27,9 @@ error_chain! {
|
|||||||
Term(::term::Error);
|
Term(::term::Error);
|
||||||
Toml(::toml::de::Error);
|
Toml(::toml::de::Error);
|
||||||
Walkdir(::walkdir::Error);
|
Walkdir(::walkdir::Error);
|
||||||
|
StripError(std::path::StripPrefixError);
|
||||||
}
|
}
|
||||||
errors { }
|
errors {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs `cargo build` to make sure the binary file is up-to-date.
|
/// Runs `cargo build` to make sure the binary file is up-to-date.
|
||||||
@ -133,8 +134,7 @@ fn run() -> crate::Result<()> {
|
|||||||
if let Some(m) = m.subcommand_matches("tauri-bundle") {
|
if let Some(m) = m.subcommand_matches("tauri-bundle") {
|
||||||
if m.is_present("version") {
|
if m.is_present("version") {
|
||||||
println!("{}", crate_version!());
|
println!("{}", crate_version!());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
let output_paths = env::current_dir()
|
let output_paths = env::current_dir()
|
||||||
.map_err(From::from)
|
.map_err(From::from)
|
||||||
.and_then(|d| Settings::new(d, m))
|
.and_then(|d| Settings::new(d, m))
|
||||||
|
Loading…
Reference in New Issue
Block a user