Generate distros.rs on build
This commit is contained in:
parent
7c874a8e9a
commit
11601933f9
6 changed files with 254 additions and 0 deletions
|
|
@ -20,6 +20,11 @@ strum = { workspace = true, features = ["derive", "std"] }
|
|||
tracing = { workspace = true, features = ["attributes", "std"] }
|
||||
tracing-subscriber = { workspace = true, features = ["ansi", "fmt", "smallvec", "std", "tracing-log"] }
|
||||
|
||||
[build-dependencies]
|
||||
indexmap = { workspace = true, features = ["std"] }
|
||||
regex = { workspace = true, features = ["perf", "std", "unicode"] }
|
||||
unicode-normalization = { workspace = true, features = ["std"] }
|
||||
|
||||
[features]
|
||||
default = ["autocomplete", "color"]
|
||||
autocomplete = ["bpaf/autocomplete"]
|
||||
|
|
|
|||
173
crates/hyfetch/build.rs
Normal file
173
crates/hyfetch/build.rs
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
use std::path::Path;
|
||||
use std::{env, fs};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use regex::Regex;
|
||||
use unicode_normalization::UnicodeNormalization;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct AsciiDistro {
|
||||
pattern: String,
|
||||
art: String,
|
||||
}
|
||||
|
||||
impl AsciiDistro {
|
||||
fn friendly_name(&self) -> String {
|
||||
self.pattern
|
||||
.split('|')
|
||||
.next()
|
||||
.expect("invalid distro pattern")
|
||||
.trim_matches(|c: char| c.is_ascii_punctuation() || c == ' ')
|
||||
.replace(['"', '*'], "")
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let neofetch_path = Path::new(env!("CARGO_WORKSPACE_DIR")).join("neofetch");
|
||||
|
||||
println!("cargo:rerun-if-changed={}", neofetch_path.display());
|
||||
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let out_path = Path::new(&out_dir);
|
||||
|
||||
export_distros(neofetch_path, out_path);
|
||||
}
|
||||
|
||||
fn export_distros<P>(neofetch_path: P, out_path: &Path)
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let distros = parse_ascii_distros(neofetch_path);
|
||||
let mut variants = IndexMap::with_capacity(distros.len());
|
||||
|
||||
for distro in &distros {
|
||||
let variant = distro
|
||||
.friendly_name()
|
||||
.replace(|c: char| c.is_ascii_punctuation() || c == ' ', "_")
|
||||
.nfc()
|
||||
.collect::<String>();
|
||||
variants.insert(variant, distro);
|
||||
}
|
||||
|
||||
let mut buf = "
|
||||
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||
pub enum Distro {
|
||||
"
|
||||
.to_owned();
|
||||
|
||||
for (variant, distro) in &variants {
|
||||
buf.push_str(&format!(
|
||||
"
|
||||
// {})
|
||||
{variant},
|
||||
",
|
||||
distro.pattern
|
||||
));
|
||||
}
|
||||
|
||||
buf.push_str(
|
||||
"
|
||||
}
|
||||
",
|
||||
);
|
||||
|
||||
buf.push_str(
|
||||
"
|
||||
impl Distro {
|
||||
pub fn ascii_art(&self) -> &str {
|
||||
let art = match self {
|
||||
",
|
||||
);
|
||||
|
||||
let quotes = "#".repeat(80);
|
||||
for (variant, distro) in &variants {
|
||||
buf.push_str(&format!(
|
||||
"
|
||||
Self::{variant} => r{quotes}\"
|
||||
{}
|
||||
\"{quotes},
|
||||
",
|
||||
distro.art
|
||||
));
|
||||
}
|
||||
|
||||
buf.push_str(
|
||||
"
|
||||
};
|
||||
&art[1..(art.len() - 1)]
|
||||
}
|
||||
}
|
||||
",
|
||||
);
|
||||
|
||||
fs::write(out_path.join("distros.rs"), buf).expect("couldn't write distros.rs");
|
||||
}
|
||||
|
||||
/// Parses ascii distros from neofetch script.
|
||||
fn parse_ascii_distros<P>(neofetch_path: P) -> Vec<AsciiDistro>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let neofetch_path = neofetch_path.as_ref();
|
||||
|
||||
let nf = {
|
||||
let nf = fs::read_to_string(neofetch_path).expect("couldn't read neofetch script");
|
||||
|
||||
// Get the content of "get_distro_ascii" function
|
||||
let (_, nf) = nf
|
||||
.split_once("get_distro_ascii() {\n")
|
||||
.expect("couldn't find get_distro_ascii function");
|
||||
let (nf, _) = nf
|
||||
.split_once("\n}\n")
|
||||
.expect("couldn't find end of get_distro_ascii function");
|
||||
|
||||
let mut nf = nf.replace('\t', &" ".repeat(4));
|
||||
|
||||
// Remove trailing spaces
|
||||
while nf.contains(" \n") {
|
||||
nf = nf.replace(" \n", "\n");
|
||||
}
|
||||
nf
|
||||
};
|
||||
|
||||
let case_re = Regex::new(r"case .*? in\n").expect("couldn't compile case regex");
|
||||
let eof_re = Regex::new(r"EOF[ \n]*?;;").expect("couldn't compile eof regex");
|
||||
|
||||
// Split by blocks
|
||||
let mut blocks = vec![];
|
||||
for b in case_re.split(&nf) {
|
||||
blocks.extend(eof_re.split(b).map(|sub| sub.trim()));
|
||||
}
|
||||
|
||||
// Parse blocks
|
||||
fn parse_block(block: &str) -> Option<AsciiDistro> {
|
||||
let (block, art) = block.split_once("'EOF'\n")?;
|
||||
|
||||
// Join \
|
||||
//
|
||||
// > A <backslash> that is not quoted shall preserve the literal value of the
|
||||
// > following character, with the exception of a <newline>. If a <newline>
|
||||
// > follows the <backslash>, the shell shall interpret this as line
|
||||
// > continuation. The <backslash> and <newline> shall be removed before
|
||||
// > splitting the input into tokens. Since the escaped <newline> is removed
|
||||
// > entirely from the input and is not replaced by any white space, it cannot
|
||||
// > serve as a token separator.
|
||||
// See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02_01
|
||||
let block = block.replace("\\\n", "");
|
||||
|
||||
// Get case pattern
|
||||
let pattern = block
|
||||
.split('\n')
|
||||
.next()
|
||||
.and_then(|pattern| pattern.trim().strip_suffix(')'))?;
|
||||
|
||||
Some(AsciiDistro {
|
||||
pattern: pattern.to_owned(),
|
||||
art: art.to_owned(),
|
||||
})
|
||||
}
|
||||
blocks
|
||||
.iter()
|
||||
.filter_map(|block| parse_block(block))
|
||||
.collect()
|
||||
}
|
||||
3
crates/hyfetch/src/distros.rs
Normal file
3
crates/hyfetch/src/distros.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#![allow(non_camel_case_types)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/distros.rs"));
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
pub mod cli_options;
|
||||
pub mod color_util;
|
||||
pub mod distros;
|
||||
pub mod neofetch_util;
|
||||
pub mod presets;
|
||||
pub mod types;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue