-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
Copy pathappimage.rs
115 lines (102 loc) · 3.64 KB
/
appimage.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright 2016-2019 Cargo-Bundle developers <https://github.com/burtonageo/cargo-bundle>
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use super::{
super::{common::CommandExt, path_utils},
debian,
};
use crate::Settings;
use anyhow::Context;
use handlebars::Handlebars;
use log::info;
use std::{
collections::BTreeMap,
fs::{remove_dir_all, write},
path::PathBuf,
process::{Command, Stdio},
};
/// Bundles the project.
/// Returns a vector of PathBuf that shows where the AppImage was created.
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_dir = settings.project_out_directory().join("bundle/appimage_deb");
// generate deb_folder structure
let (_, icons) = debian::generate_data(settings, &package_dir)?;
let icons: Vec<debian::DebIcon> = icons.into_iter().collect();
let output_path = settings.project_out_directory().join("bundle/appimage");
if output_path.exists() {
remove_dir_all(&output_path)?;
}
std::fs::create_dir_all(output_path.clone())?;
let app_dir_path = output_path.join(format!("{}.AppDir", settings.main_binary_name()));
let appimage_filename = format!(
"{}_{}_{}.AppImage",
settings.main_binary_name(),
settings.version_string(),
arch
);
let appimage_path = output_path.join(&appimage_filename);
path_utils::create(app_dir_path, true)?;
let upcase_app_name = settings.main_binary_name().to_uppercase();
// setup data to insert into shell script
let mut sh_map = BTreeMap::new();
sh_map.insert("arch", settings.target().split('-').next().unwrap());
sh_map.insert("app_name", settings.main_binary_name());
sh_map.insert("app_name_uppercase", &upcase_app_name);
sh_map.insert("appimage_filename", &appimage_filename);
let tauri_tools_path = dirs_next::cache_dir().map_or_else(
|| output_path.to_path_buf(),
|mut p| {
p.push("tauri");
p
},
);
std::fs::create_dir_all(&tauri_tools_path)?;
let tauri_tools_path_str = tauri_tools_path.to_string_lossy();
sh_map.insert("tauri_tools_path", &tauri_tools_path_str);
let larger_icon = icons
.iter()
.filter(|i| i.width == i.height)
.max_by_key(|i| i.width)
.expect("couldn't find a square icon to use as AppImage icon");
let larger_icon_path = larger_icon
.path
.strip_prefix(package_dir.join("data"))
.unwrap()
.to_string_lossy()
.to_string();
sh_map.insert("icon_path", &larger_icon_path);
// initialize shell script template.
let mut handlebars = Handlebars::new();
handlebars.register_escape_fn(handlebars::no_escape);
handlebars
.register_template_string("appimage", include_str!("templates/appimage"))
.expect("Failed to register template for handlebars");
let temp = handlebars.render("appimage", &sh_map)?;
// create the shell script file in the target/ folder.
let sh_file = output_path.join("build_appimage.sh");
info!(action = "Bundling"; "{} ({})", appimage_filename, appimage_path.display());
write(&sh_file, temp)?;
// chmod script for execution
Command::new("chmod")
.arg("777")
.arg(&sh_file)
.current_dir(output_path.clone())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.expect("Failed to chmod script");
// execute the shell script to build the appimage.
Command::new(&sh_file)
.current_dir(output_path)
.output_ok()
.context("error running appimage.sh")?;
remove_dir_all(&package_dir)?;
Ok(vec![appimage_path])
}