refactor(Bundler, API) clean up external binary logic (#332)

* refactor external binary logic

* update regex and error.

* refactor bundle_settings external bin

* fix bug

* cleanup api

* cleanup windows deps.

* add windows macro
This commit is contained in:
Tensor-Programming
2020-01-16 22:19:21 -05:00
committed by GitHub
parent 6225e5d30a
commit b9f3d9a92c
10 changed files with 114 additions and 79 deletions

View File

@@ -35,6 +35,7 @@ walkdir = "2"
[target.'cfg(target_os = "windows")'.dependencies]
attohttpc = { version = "0.10.1" }
regex = { version = "1" }
[target.'cfg(not(target_os = "linux"))'.dependencies]
handlebars = { version = "2.0" }
@@ -42,7 +43,6 @@ lazy_static = { version = "1.4" }
zip = { version = "0.5" }
sha2 = { version = "0.8" }
hex = { version = "0.4" }
regex = { version = "1" }
[dev-dependencies]
tempfile = "3"

View File

@@ -42,14 +42,7 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<PathBuf>> {
});
}
// copy external binaries to out dir for testing
let out_dir = settings.project_out_directory();
for src in settings.external_binaries() {
let src = src?;
let dest = out_dir.join(src.file_name().expect("failed to extract external binary filename"));
common::copy_file(&src, &dest)
.map_err(|_| format!("Failed to copy external binary {:?}", src))?;
}
settings.copy_binaries(settings.project_out_directory())?;
Ok(paths)
}

View File

@@ -88,10 +88,16 @@ pub fn generate_folders(settings: &Settings, package_dir: &Path) -> crate::Resul
// Generate data files.
let data_dir = package_dir.join("data");
let binary_dest = data_dir.join("usr/bin").join(settings.binary_name());
let bin_dir = data_dir.join("usr/bin");
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")?;
transfer_external_binaries(settings, &data_dir).chain_err(|| "Failed to copy external binaries")?;
settings
.copy_binaries(&bin_dir)
.chain_err(|| "Failed to copy external binaries")?;
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")?;
@@ -213,19 +219,6 @@ fn transfer_resource_files(settings: &Settings, data_dir: &Path) -> crate::Resul
Ok(())
}
/// Copy the bundle's external binaries into an appropriate directory under the
/// `data_dir`.
fn transfer_external_binaries(settings: &Settings, data_dir: &Path) -> crate::Result<()> {
let bin_dir = data_dir.join("usr/bin");
for src in settings.external_binaries() {
let src = src?;
let dest = bin_dir.join(src.file_name().expect("failed to extract external binary filename"));
common::copy_file(&src, &dest)
.chain_err(|| format!("Failed to copy external binary {:?}", src))?;
}
Ok(())
}
/// Generate the icon files and store them under the `data_dir`.
fn generate_icon_files(settings: &Settings, data_dir: &PathBuf) -> crate::Result<()> {
let base_dir = data_dir.join("usr/share/icons/hicolor");

View File

@@ -68,12 +68,9 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
.chain_err(|| format!("Failed to copy resource file {:?}", src))?;
}
for src in settings.external_binaries() {
let src = src?;
let dest = bin_dir.join(src.file_name().expect("failed to extract external binary filename"));
common::copy_file(&src, &dest)
.chain_err(|| format!("Failed to copy external binary {:?}", src))?;
}
settings
.copy_binaries(&bin_dir)
.chain_err(|| "Failed to copy external binaries")?;
copy_binary_to_bundle(&bundle_directory, settings)
.chain_err(|| format!("Failed to copy binary from {:?}", settings.binary_path()))?;

View File

@@ -1,4 +1,7 @@
use super::category::AppCategory;
use crate::bundle::common;
use crate::platform::target_triple;
use clap::ArgMatches;
use glob;
use std;
@@ -9,7 +12,6 @@ use std::path::{Path, PathBuf};
use target_build_utils::TargetInfo;
use toml;
use walkdir;
use crate::platform::{target_triple};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PackageType {
@@ -120,7 +122,7 @@ struct PackageSettings {
description: String,
homepage: Option<String>,
authors: Option<Vec<String>>,
metadata: Option<MetadataSettings>
metadata: Option<MetadataSettings>,
}
#[derive(Clone, Debug, Deserialize)]
@@ -209,7 +211,7 @@ impl Settings {
} else {
bail!("No [package.metadata.bundle] section in Cargo.toml");
};
let (mut bundle_settings, binary_name) = match build_artifact {
let (bundle_settings, binary_name) = match build_artifact {
BuildArtifact::Main => (bundle_settings, package.name.clone()),
BuildArtifact::Bin(ref name) => (
bundle_settings_from_table(&bundle_settings.bin, "bin", name)?,
@@ -227,24 +229,7 @@ impl Settings {
};
let binary_path = target_dir.join(&binary_name);
let target_triple = target_triple()?;
let mut win_paths = Vec::new();
match bundle_settings.external_bin {
Some(paths) => {
for curr_path in paths.iter() {
win_paths.push(
format!(
"{}-{}{}",
curr_path,
target_triple,
if cfg!(windows) { ".exe" } else { "" }
)
);
}
bundle_settings.external_bin = Some(win_paths);
},
None => { }
}
let bundle_settings = add_external_bin(bundle_settings)?;
Ok(Settings {
package,
@@ -445,6 +430,21 @@ impl Settings {
}
}
// copy external binaries to a path.
pub fn copy_binaries(&self, path: &Path) -> crate::Result<()> {
for src in self.external_binaries() {
let src = src?;
let dest = path.join(
src
.file_name()
.expect("failed to extract external binary filename"),
);
common::copy_file(&src, &dest)
.map_err(|_| format!("Failed to copy external binary {:?}", src))?;
}
Ok(())
}
pub fn version_string(&self) -> &str {
self
.bundle_settings
@@ -541,6 +541,30 @@ fn bundle_settings_from_table(
}
}
fn add_external_bin(bundle_settings: BundleSettings) -> crate::Result<BundleSettings> {
let target_triple = target_triple()?;
let mut win_paths = Vec::new();
let external_bin = match bundle_settings.external_bin {
Some(paths) => {
for curr_path in paths.iter() {
win_paths.push(format!(
"{}-{}{}",
curr_path,
target_triple,
if cfg!(windows) { ".exe" } else { "" }
));
}
Some(win_paths)
}
None => Some(vec![String::from("")]),
};
Ok(BundleSettings {
external_bin,
..bundle_settings
})
}
pub struct ResourcePaths<'a> {
pattern_iter: std::slice::Iter<'a, String>,
glob_iter: Option<glob::Paths>,

View File

@@ -2,10 +2,10 @@ use super::common;
use super::path_utils::{copy, Options};
use super::settings::Settings;
use handlebars::{Handlebars, to_json};
use handlebars::{to_json, Handlebars};
use lazy_static::lazy_static;
use sha2::Digest;
use regex::Regex;
use sha2::Digest;
use std::collections::BTreeMap;
use std::fs::{create_dir_all, remove_dir_all, write, File};
@@ -53,6 +53,13 @@ lazy_static! {
};
}
#[derive(Serialize)]
struct ExternalBinary {
guid: String,
id: String,
path: String,
}
fn copy_icons(settings: &Settings) -> crate::Result<PathBuf> {
let base_dir = settings.binary_path();
let base_dir = base_dir.parent().expect("Failed to get dir");
@@ -366,25 +373,8 @@ pub fn build_wix_app_installer(
let app_exe_name = settings.binary_name().to_string();
data.insert("app_exe_name", to_json(&app_exe_name));
#[derive(Serialize)]
struct ExternalBinary {
guid: String,
id: String,
path: String
}
let mut external_binaries = Vec::new();
let regex = Regex::new("[^A-Za-z0-9\\._]").unwrap();
let cwd = std::env::current_dir()?;
for src in settings.external_binaries() {
let src = src?;
let filename = src.file_name().expect("failed to extract external binary filename").to_os_string().into_string().expect("failed to convert external binary filename to string");
let guid = generate_guid(filename.as_bytes()).to_string();
external_binaries.push(ExternalBinary {
guid: guid,
path: cwd.join(src).into_os_string().into_string().expect("failed to read external binary path"),
id: regex.replace_all(&filename, "").to_string()
});
}
let external_binaries = generate_external_binary_data(&settings)?;
let external_binaries_json = to_json(&external_binaries);
data.insert("external_binaries", external_binaries_json);
@@ -429,3 +419,32 @@ pub fn build_wix_app_installer(
Ok(target)
}
fn generate_external_binary_data(settings: &Settings) -> crate::Result<Vec<ExternalBinary>> {
let mut external_binaries = Vec::new();
let regex = Regex::new(r"[^\w\d\.]")?;
let cwd = std::env::current_dir()?;
for src in settings.external_binaries() {
let src = src?;
let filename = src
.file_name()
.expect("failed to extract external binary filename")
.to_os_string()
.into_string()
.expect("failed to convert external binary filename to string");
let guid = generate_guid(filename.as_bytes()).to_string();
external_binaries.push(ExternalBinary {
guid: guid,
path: cwd
.join(src)
.into_os_string()
.into_string()
.expect("failed to read external binary path"),
id: regex.replace_all(&filename, "").to_string(),
});
}
Ok(external_binaries)
}

View File

@@ -28,9 +28,10 @@ error_chain! {
Term(::term::Error);
Toml(::toml::de::Error);
Walkdir(::walkdir::Error);
HttpError(::attohttpc::Error) #[cfg(windows)];
StripError(std::path::StripPrefixError);
ConvertError(std::num::TryFromIntError);
RegexError(::regex::Error) #[cfg(windows)];
HttpError(::attohttpc::Error) #[cfg(windows)];
}
errors {}
}

View File

@@ -1,5 +1,7 @@
use std::process::{Child, Command, Stdio};
use crate::platform;
pub fn get_output(cmd: String, args: Vec<String>, stdout: Stdio) -> crate::Result<String> {
Command::new(cmd)
.args(args)
@@ -51,12 +53,8 @@ pub fn spawn_relative_command(
Ok(Command::new(cmd).args(args).stdout(stdout).spawn()?)
}
pub fn binary_command(binary_name: String) -> Result<String, String> {
return Ok(format!(
"{}-{}",
binary_name,
crate::platform::target_triple()?
));
pub fn binary_command(binary_name: String) -> crate::Result<String> {
return Ok(format!("{}-{}", binary_name, platform::target_triple()?));
}
// tests for the commands functions.

View File

@@ -1,3 +1,8 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
#[cfg(test)]
extern crate quickcheck;
#[cfg(test)]
@@ -7,9 +12,9 @@ extern crate quickcheck_macros;
pub mod command;
pub mod dir;
pub mod file;
pub mod platform;
pub mod rpc;
pub mod version;
pub mod platform;
use error_chain::error_chain;

View File

@@ -1,3 +1,8 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
#[macro_use]
extern crate serde_derive;
extern crate serde_json;