Build css with rust

This commit is contained in:
Adrian Woźniak 2020-04-23 14:26:43 +02:00
parent a4ab4a7a42
commit 7c5b63fa2c
7 changed files with 281 additions and 3 deletions

122
Cargo.lock generated
View File

@ -967,6 +967,18 @@ dependencies = [
"ascii_utils",
]
[[package]]
name = "filetime"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f59efc38004c988e4201d11d263b8171f49a2e7ec0bdbb71773433f271504a5e"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"winapi 0.3.8",
]
[[package]]
name = "flate2"
version = "1.0.14"
@ -1000,6 +1012,25 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "fsevent"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
dependencies = [
"bitflags",
"fsevent-sys",
]
[[package]]
name = "fsevent-sys"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0"
dependencies = [
"libc",
]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
@ -1157,6 +1188,12 @@ dependencies = [
"wasi",
]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "gloo-timers"
version = "0.2.1"
@ -1283,6 +1320,26 @@ dependencies = [
"autocfg 1.0.0",
]
[[package]]
name = "inotify"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24e40d6fd5d64e2082e0c796495c8ef5ad667a96d03e5aaa0becfd9d47bcbfb8"
dependencies = [
"bitflags",
"inotify-sys",
"libc",
]
[[package]]
name = "inotify-sys"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
dependencies = [
"libc",
]
[[package]]
name = "iovec"
version = "0.1.4"
@ -1341,6 +1398,15 @@ dependencies = [
"web-sys",
]
[[package]]
name = "jirs-css"
version = "0.1.0"
dependencies = [
"clap",
"glob",
"notify",
]
[[package]]
name = "jirs-data"
version = "0.1.0"
@ -1424,6 +1490,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
[[package]]
name = "lettre"
version = "0.9.2"
@ -1577,6 +1649,18 @@ dependencies = [
"winapi 0.2.8",
]
[[package]]
name = "mio-extras"
version = "2.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
dependencies = [
"lazycell",
"log 0.4.8",
"mio",
"slab",
]
[[package]]
name = "mio-uds"
version = "0.6.7"
@ -1639,6 +1723,24 @@ dependencies = [
"version_check 0.1.5",
]
[[package]]
name = "notify"
version = "4.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
dependencies = [
"bitflags",
"filetime",
"fsevent",
"fsevent-sys",
"inotify",
"libc",
"mio",
"mio-extras",
"walkdir",
"winapi 0.3.8",
]
[[package]]
name = "num-bigint"
version = "0.2.6"
@ -2189,6 +2291,15 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "schannel"
version = "0.1.18"
@ -2713,6 +2824,17 @@ version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
[[package]]
name = "walkdir"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
dependencies = [
"same-file",
"winapi 0.3.8",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"

View File

@ -14,5 +14,6 @@ members = [
"./jirs-server",
"./jirs-client",
"./jirs-data",
"./jirs-css",
]

View File

@ -18,6 +18,7 @@
"svgo": "^1.3.2",
"svgo-loader": "^2.2.1",
"swc-loader": "^0.1.8",
"watchpack": "^1.6.1",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"

View File

@ -40,9 +40,7 @@ module.exports = {
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
// options: { importLoaders: 1 }
},
// 'postcss-loader'
],
},
{

View File

@ -6155,7 +6155,7 @@ vm-browserify@^1.0.1:
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
watchpack@^1.6.0:
watchpack@^1.6.0, watchpack@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.1.tgz#280da0a8718592174010c078c7585a74cd8cd0e2"
integrity sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==

12
jirs-css/Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "jirs-css"
version = "0.1.0"
authors = ["Adrian Woźniak <adrian.wozniak.1986@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "*", features = [] }
glob = { version = "*" }
notify = { version = "*" }

144
jirs-css/src/main.rs Normal file
View File

@ -0,0 +1,144 @@
use std::fs::*;
use std::io::Read;
use std::path::Path;
use std::time::SystemTime;
const INPUT: &str = "./jirs-client/js/styles.css";
#[derive(Debug, Default)]
struct Configuration {
input: String,
output: Option<String>,
watch: bool,
prelude_selector: bool,
files: Vec<String>,
}
impl Configuration {
pub fn scan_fs(&mut self) -> Result<(), String> {
let input_dir = Path::new(self.input.as_str())
.parent()
.ok_or_else(|| format!("Not a valid path {:?}", self.input))?;
let path = input_dir.to_str().unwrap();
let paths =
glob::glob(format!("{}/**/*.css", path).as_str()).map_err(|e| format!("{}", e))?;
for path in paths.filter_map(Result::ok) {
self.files.push(path.display().to_string());
}
Ok(())
}
}
fn merge_files(input: &Path, out: &mut Vec<String>) -> Result<(), String> {
let input_dir = input
.clone()
.parent()
.ok_or_else(|| format!("Not a valid path {:?}", input))?;
let contents: String =
read_to_string(input).map_err(|_| format!("File cannot be read {:?}", input))?;
for line in contents.lines() {
if line.trim().is_empty() {
continue;
}
if !line.starts_with("@import ") {
out.push(line.to_string());
continue;
}
let imported = {
line.replace("@import ", "")
.trim()
.replace("\"", "")
.replace(";", "")
.to_string()
};
let child = input_dir.clone().join(imported.as_str());
merge_files(child.as_path(), out)?;
}
Ok(())
}
fn read_timestamp(input: &Path) -> Result<SystemTime, String> {
std::fs::File::open(input)
.and_then(|file| file.metadata())
.and_then(|meta| meta.modified())
.map_err(|e| format!("{}", e))
}
fn check_timestamps(input: &Path, output_timestamp: SystemTime) -> Result<bool, String> {
let input_dir = input
.clone()
.parent()
.ok_or_else(|| format!("Not a valid path {:?}", input))?;
let path = input_dir.to_str().unwrap();
let paths = glob::glob(format!("{}/**/*.css", path).as_str()).map_err(|e| format!("{}", e))?;
for path in paths.filter_map(Result::ok) {
if read_timestamp(path.as_path())? > output_timestamp {
return Ok(false);
}
}
Ok(true)
}
fn main() -> Result<(), String> {
let matches = clap::App::new("jirs-css")
.arg(
clap::Arg::with_name("input")
.short("i")
.default_value(INPUT)
.takes_value(true),
)
.arg(clap::Arg::with_name("output").short("O").takes_value(true))
.arg(clap::Arg::with_name("watch").short("W"))
.arg(
clap::Arg::with_name("prelude")
.short("p")
.help("Prepend file name as class to each selector"),
)
.get_matches();
let mut config = Configuration {
input: matches.value_of("input").unwrap().to_string(),
output: matches.value_of("output").map(|s| s.to_string()),
watch: matches.is_present("watch"),
prelude_selector: matches.is_present("prelude"),
files: vec![],
};
config.scan_fs()?;
println!("{:?}", config);
let output_timestamp = matches
.value_of("output")
.ok_or(std::io::Error::from_raw_os_error(0))
.and_then(|path| File::open(path))
.and_then(|file| file.metadata())
.and_then(|meta| meta.modified())
.unwrap_or_else(|_| SystemTime::UNIX_EPOCH.clone());
let mut file =
std::fs::File::open(matches.value_of("input").unwrap()).map_err(|e| format!("{}", e))?;
let input = matches.value_of("input").unwrap();
if check_timestamps(Path::new(input), output_timestamp)? {
return Ok(());
}
let mut contents: String = String::new();
file.read_to_string(&mut contents)
.map_err(|e| format!("{}", e))?;
let mut out = vec![];
merge_files(std::path::Path::new(input), &mut out)?;
match matches.value_of("output") {
Some(output) => {
std::fs::create_dir_all(Path::new(output).parent().unwrap()).unwrap();
std::fs::write(output, out.join("\n")).unwrap()
}
None => println!("{}", out.join("\n")),
}
Ok(())
}