2022-05-02 07:56:39 +00:00
|
|
|
#[cfg(windows)]
|
2022-05-01 10:15:59 +00:00
|
|
|
use anyhow::Context;
|
2022-05-07 12:16:30 +00:00
|
|
|
use neutauri_data as data;
|
2022-05-02 07:56:39 +00:00
|
|
|
#[cfg(windows)]
|
2022-05-01 08:41:32 +00:00
|
|
|
use std::{
|
2022-05-02 07:56:39 +00:00
|
|
|
env,
|
2022-05-01 08:41:32 +00:00
|
|
|
hash::{Hash, Hasher},
|
|
|
|
};
|
2022-05-07 12:16:30 +00:00
|
|
|
use std::{
|
|
|
|
fs,
|
|
|
|
io::{self, Write},
|
|
|
|
};
|
2022-04-04 15:53:17 +00:00
|
|
|
|
|
|
|
fn options() -> fs::OpenOptions {
|
|
|
|
#[cfg(not(windows))]
|
|
|
|
use std::os::unix::prelude::OpenOptionsExt;
|
|
|
|
let mut options = fs::OpenOptions::new();
|
|
|
|
options.write(true);
|
|
|
|
options.create(true);
|
|
|
|
options.truncate(true);
|
|
|
|
#[cfg(not(windows))]
|
|
|
|
options.mode(0o755);
|
|
|
|
options
|
|
|
|
}
|
|
|
|
|
2022-05-01 08:41:32 +00:00
|
|
|
#[cfg(not(windows))]
|
2022-05-02 07:56:39 +00:00
|
|
|
fn get_runtime_data(
|
|
|
|
_icon_path: Option<std::path::PathBuf>,
|
|
|
|
_manifest_path: Option<std::path::PathBuf>,
|
|
|
|
) -> anyhow::Result<Vec<u8>> {
|
2022-05-01 08:41:32 +00:00
|
|
|
Ok(include_bytes!("../../target/release/neutauri_runtime").to_vec())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(windows)]
|
2022-05-01 11:59:22 +00:00
|
|
|
fn get_runtime_data(
|
|
|
|
icon_path: Option<std::path::PathBuf>,
|
|
|
|
manifest_path: Option<std::path::PathBuf>,
|
|
|
|
) -> anyhow::Result<Vec<u8>> {
|
2022-05-01 08:41:32 +00:00
|
|
|
let mut hasher = std::collections::hash_map::DefaultHasher::new();
|
|
|
|
hasher.write(b"neutauri_runtime");
|
|
|
|
std::time::SystemTime::now().hash(&mut hasher);
|
|
|
|
let temp_path = env::temp_dir().join(format!("{:x}.exe", hasher.finish()));
|
|
|
|
fs::write(
|
|
|
|
&temp_path,
|
|
|
|
include_bytes!("../../target/release/neutauri_runtime.exe"),
|
|
|
|
)?;
|
2022-05-01 11:59:22 +00:00
|
|
|
let mut updater = rcedit::ResourceUpdater::new();
|
|
|
|
updater.load(&temp_path)?;
|
|
|
|
if let Some(icon_path) = icon_path {
|
|
|
|
println!("{:?}", fs::canonicalize(&icon_path)?);
|
|
|
|
updater.set_icon(&fs::canonicalize(icon_path)?)?;
|
|
|
|
}
|
|
|
|
if let Some(manifest_path) = manifest_path {
|
|
|
|
updater.set_application_manifest(&fs::canonicalize(manifest_path)?)?;
|
|
|
|
}
|
|
|
|
updater.commit()?;
|
|
|
|
drop(updater);
|
|
|
|
let runtime_data =
|
|
|
|
fs::read(&temp_path).with_context(|| format!("Failed to read {}", temp_path.display()))?;
|
|
|
|
fs::remove_file(&temp_path)?;
|
|
|
|
Ok(runtime_data)
|
2022-05-01 08:41:32 +00:00
|
|
|
}
|
|
|
|
|
2022-05-01 10:15:59 +00:00
|
|
|
pub fn bundle(config_path: String) -> anyhow::Result<()> {
|
2022-04-04 15:53:17 +00:00
|
|
|
let config_path = std::path::Path::new(&config_path).canonicalize()?;
|
|
|
|
let config: data::Config = toml::from_str(fs::read_to_string(&config_path)?.as_str())
|
2022-05-01 08:41:32 +00:00
|
|
|
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
|
2022-04-04 15:53:17 +00:00
|
|
|
let source = match config_path.parent() {
|
|
|
|
Some(path) => path.join(&config.source).canonicalize()?,
|
|
|
|
None => config.source.canonicalize()?,
|
|
|
|
};
|
|
|
|
let target = match config_path.parent() {
|
|
|
|
Some(path) => data::normalize_path(&path.join(&config.target)),
|
|
|
|
None => data::normalize_path(&config.target),
|
|
|
|
};
|
2022-05-01 05:58:32 +00:00
|
|
|
fs::create_dir_all(target.parent().unwrap_or_else(|| std::path::Path::new("/")))?;
|
2022-04-04 15:53:17 +00:00
|
|
|
let target = if target.extension() == None && cfg!(windows) {
|
|
|
|
target.with_extension("exe")
|
|
|
|
} else {
|
|
|
|
target
|
|
|
|
};
|
|
|
|
if target.extension() == Some(std::ffi::OsStr::new("neu")) {
|
|
|
|
data::pack(config_path)?;
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
let data = data::Data::build_from_dir(source, config.window_attr()?, config.webview_attr()?)?;
|
|
|
|
let mut f = options().open(&target)?;
|
2022-05-01 11:59:22 +00:00
|
|
|
f.write_all(&get_runtime_data(config.icon, config.manifest)?)?;
|
2022-04-04 15:53:17 +00:00
|
|
|
f.write_all(&data)?;
|
|
|
|
f.sync_all()?;
|
|
|
|
f.flush()?;
|
|
|
|
Ok(())
|
|
|
|
}
|