Merge pull request #37 from mrxiaozhuox/master

Add SASS support
This commit is contained in:
YuKun Liu authored and GitHub committed 2022-06-02 15:29:33 +08:00
commit 62d18441c7
5 files changed
+264 -10

No files matched your search

+4
View File
@@ -39,11 +39,15 @@ hyper = "0.14.17"
axum = { version = "0.5.1", features = ["ws", "headers"] }
tower-http = { version = "0.2.2", features = ["fs", "trace"] }
headers = "0.3.7"
walkdir = "2"
# tools download
dirs = "4.0.0"
reqwest = { version = "0.11", features = ["rustls-tls", "stream", "trust-dns"] }
flate2 = "1.0.22"
tar = "0.4.38"
zip = "0.6.2"
tower = "0.4.12"
[[bin]]
+16 -1
View File
@@ -42,4 +42,19 @@ script = []
# use binaryen.wasm-opt for output Wasm file
# binaryen just will trigger in `web` platform
binaryen = { wasm_opt = true }
binaryen = { wasm_opt = true }
# use sass auto will auto check sass file and build it.
[application.tools.sass]
# auto will check the assets dirs, and auto to transform all scss file to css file.
input = "*"
# or you can specify some scss file -> css file
# input = [
# # some sass file path
# # this file will translate to `/css/test.css`
# "/css/test.scss"
# ]
source_map = true
+164
View File
@@ -1,6 +1,7 @@
use crate::{
config::{CrateConfig, ExecutableType},
error::{Error, Result},
tools::Tool,
DioxusConfig,
};
use std::{
@@ -29,6 +30,9 @@ pub fn build(config: &CrateConfig) -> Result<()> {
..
} = config;
// start to build the assets
let ignore_files = build_assets(config)?;
let t_start = std::time::Instant::now();
// [1] Build the .wasm module
@@ -154,6 +158,13 @@ pub fn build(config: &CrateConfig) -> Result<()> {
log::warn!("Error copying dir: {}", _e);
}
}
for ignore in &ignore_files {
let ignore = ignore.strip_prefix(&config.asset_dir).unwrap();
let ignore = config.out_dir.join(ignore);
if ignore.is_file() {
std::fs::remove_file(ignore)?;
}
}
}
}
}
@@ -166,6 +177,8 @@ pub fn build(config: &CrateConfig) -> Result<()> {
pub fn build_desktop(config: &CrateConfig, is_serve: bool) -> Result<()> {
log::info!("🚅 Running build [Desktop] command...");
let ignore_files = build_assets(config)?;
let mut cmd = Command::new("cargo");
cmd.current_dir(&config.crate_dir)
.arg("build")
@@ -250,6 +263,13 @@ pub fn build_desktop(config: &CrateConfig, is_serve: bool) -> Result<()> {
log::warn!("Error copying dir: {}", e);
}
}
for ignore in &ignore_files {
let ignore = ignore.strip_prefix(&config.asset_dir).unwrap();
let ignore = config.out_dir.join(ignore);
if ignore.is_file() {
std::fs::remove_file(ignore)?;
}
}
}
}
}
@@ -339,6 +359,150 @@ pub fn gen_page(config: &DioxusConfig, serve: bool) -> String {
html.replace("{app_title}", &title)
}
// this function will build some assets file
// like sass tool resources
// this function will return a array which file don't need copy to out_dir.
fn build_assets(config: &CrateConfig) -> Result<Vec<PathBuf>> {
let mut result = vec![];
let dioxus_config = &config.dioxus_config;
let dioxus_tools = dioxus_config.application.tools.clone().unwrap_or_default();
// check sass tool state
let sass = Tool::Sass;
if sass.is_installed() && dioxus_tools.contains_key("sass") {
let sass_conf = dioxus_tools.get("sass").unwrap();
if let Some(tab) = sass_conf.as_table() {
let source_map = tab.contains_key("source_map");
let source_map = if source_map && tab.get("source_map").unwrap().is_bool() {
if tab.get("source_map").unwrap().as_bool().unwrap_or_default() {
"--source-map"
} else {
"--no-source-map"
}
} else {
"--source-map"
};
if tab.contains_key("input") {
if tab.get("input").unwrap().is_str() {
let file = tab.get("input").unwrap().as_str().unwrap().trim();
if file == "*" {
// if the sass open auto, we need auto-check the assets dir.
let asset_dir = config.asset_dir.clone();
if asset_dir.is_dir() {
for entry in walkdir::WalkDir::new(&asset_dir)
.into_iter()
.filter_map(|e| e.ok())
{
let temp = entry.path();
if temp.is_file() {
let suffix = temp.extension();
if suffix.is_none() { continue; }
let suffix = suffix.unwrap().to_str().unwrap();
if suffix == "scss" || suffix == "sass" {
// if file suffix is `scss` / `sass` we need transform it.
let out_file = format!(
"{}.css",
temp.file_stem().unwrap().to_str().unwrap()
);
let target_path = config
.out_dir
.join(
temp.strip_prefix(&asset_dir)
.unwrap()
.parent()
.unwrap(),
)
.join(out_file);
let res = sass.call(
"sass",
vec![
temp.to_str().unwrap(),
target_path.to_str().unwrap(),
source_map,
],
);
if res.is_ok() {
result.push(temp.to_path_buf());
}
}
}
}
}
} else {
// just transform one file.
let relative_path = if &file[0..1] == "/" {
&file[1..file.len()]
} else {
file
};
let path = config.asset_dir.join(relative_path);
let out_file =
format!("{}.css", path.file_stem().unwrap().to_str().unwrap());
let target_path = config
.out_dir
.join(PathBuf::from(relative_path).parent().unwrap())
.join(out_file);
if path.is_file() {
let res = sass.call(
"sass",
vec![
path.to_str().unwrap(),
target_path.to_str().unwrap(),
source_map,
],
);
if res.is_ok() {
result.push(path);
} else {
log::error!("{:?}", res);
}
}
}
} else if tab.get("input").unwrap().is_array() {
// check files list.
let list = tab.get("input").unwrap().as_array().unwrap();
for i in list {
if i.is_str() {
let path = i.as_str().unwrap();
let relative_path = if &path[0..1] == "/" {
&path[1..path.len()]
} else {
path
};
let path = config.asset_dir.join(relative_path);
let out_file =
format!("{}.css", path.file_stem().unwrap().to_str().unwrap());
let target_path = config
.out_dir
.join(PathBuf::from(relative_path).parent().unwrap())
.join(out_file);
if path.is_file() {
let res = sass.call(
"sass",
vec![
path.to_str().unwrap(),
target_path.to_str().unwrap(),
source_map,
],
);
if res.is_ok() {
result.push(path);
}
}
}
}
}
}
}
}
// SASS END
Ok(result)
}
// use binary_install::{Cache, Download};
// /// Attempts to find `wasm-opt` in `PATH` locally, or failing that downloads a
+7 -4
View File
@@ -20,14 +20,18 @@ impl Tool {
Tool::List {} => {
for item in tools::tool_list() {
if tools::Tool::from_str(item).unwrap().is_installed() {
println!("{item} [installed]");
println!("- {item} [installed]");
} else {
println!("{item}");
println!("- {item}");
}
}
}
Tool::AppPath {} => {
println!("{}", tools::tools_path().to_str().unwrap());
if let Some(v) = tools::tools_path().to_str() {
println!("{}", v);
} else {
log::error!("Tools path get failed.");
}
}
Tool::Add { name } => {
let tool_list = tools::tool_list();
@@ -58,7 +62,6 @@ impl Tool {
log::info!("Tool {name} install successfully!");
}
}
Ok(())
}
}
+73 -5
View File
@@ -1,6 +1,6 @@
use std::{
fs::{create_dir_all, File},
path::PathBuf,
path::{Path, PathBuf},
process::Command,
};
@@ -13,10 +13,11 @@ use tokio::io::AsyncWriteExt;
#[derive(Debug, PartialEq, Eq)]
pub enum Tool {
Binaryen,
Sass,
}
pub fn tool_list() -> Vec<&'static str> {
vec!["binaryen"]
vec!["binaryen", "sass"]
}
pub fn app_path() -> PathBuf {
@@ -52,6 +53,7 @@ impl Tool {
pub fn from_str(name: &str) -> Option<Self> {
match name {
"binaryen" => Some(Self::Binaryen),
"sass" => Some(Self::Sass),
_ => None,
}
}
@@ -60,6 +62,7 @@ impl Tool {
pub fn name(&self) -> &str {
match self {
Self::Binaryen => "binaryen",
Self::Sass => "sass",
}
}
@@ -67,6 +70,7 @@ impl Tool {
pub fn bin_path(&self) -> &str {
match self {
Self::Binaryen => "bin",
Self::Sass => ".",
}
}
@@ -84,6 +88,17 @@ impl Tool {
panic!("unsupported platformm");
}
}
Self::Sass => {
if cfg!(target_os = "windows") {
"windows"
} else if cfg!(target_os = "macos") {
"macos"
} else if cfg!(target_os = "linux") {
"linux"
} else {
panic!("unsupported platformm");
}
}
}
}
@@ -96,6 +111,13 @@ impl Tool {
target = self.target_platform()
)
}
Self::Sass => {
format!(
"https://github.com/sass/dart-sass/releases/download/1.51.0/dart-sass-1.51.0-{target}-x64.{extension}",
target = self.target_platform(),
extension = self.extension()
)
}
}
}
@@ -103,6 +125,13 @@ impl Tool {
pub fn extension(&self) -> &str {
match self {
Self::Binaryen => "tar.gz",
Self::Sass => {
if cfg!(target_os = "windows") {
"zip"
} else {
"tar.gz"
}
}
}
}
@@ -131,7 +160,7 @@ impl Tool {
let chunk = chunk_res.context("error reading chunk from download")?;
let _ = file.write(chunk.as_ref()).await;
}
// log::info!("temp file path: {:?}", temp_out);
Ok(temp_out)
}
@@ -143,7 +172,7 @@ impl Tool {
let dir_name = if self == &Tool::Binaryen {
"binaryen-version_105"
} else {
""
"dart-sass"
};
if self.extension() == "tar.gz" {
@@ -151,7 +180,10 @@ impl Tool {
let tar = GzDecoder::new(tar_gz);
let mut archive = Archive::new(tar);
archive.unpack(&tool_path)?;
// println!("{:?} -> {:?}", tool_path.join(dir_name), tool_path.join(self.name()));
std::fs::rename(tool_path.join(dir_name), tool_path.join(self.name()))?;
} else if self.extension() == "zip" {
// decompress the `zip` file
extract_zip(&temp_path, &tool_path)?;
std::fs::rename(tool_path.join(dir_name), tool_path.join(self.name()))?;
}
@@ -169,6 +201,13 @@ impl Tool {
command.to_string()
}
}
Tool::Sass => {
if cfg!(target_os = "windows") {
format!("{}.bat", command)
} else {
command.to_string()
}
}
};
if !bin_path.join(&command_file).is_file() {
@@ -185,3 +224,32 @@ impl Tool {
Ok(output.stdout)
}
}
fn extract_zip(file: &Path, target: &Path) -> anyhow::Result<()> {
let zip_file = std::fs::File::open(&file)?;
let mut zip = zip::ZipArchive::new(zip_file)?;
if !target.exists() {
let _ = std::fs::create_dir_all(target)?;
}
for i in 0..zip.len() {
let mut file = zip.by_index(i)?;
if file.is_dir() {
// dir
let target = target.join(Path::new(&file.name().replace('\\', "")));
let _ = std::fs::create_dir_all(target)?;
} else {
// file
let file_path = target.join(Path::new(file.name()));
let mut target_file = if !file_path.exists() {
std::fs::File::create(file_path)?
} else {
std::fs::File::open(file_path)?
};
let _num = std::io::copy(&mut file, &mut target_file)?;
}
}
Ok(())
}