Browse Source

cli-docs: compress included text

master
Manos Pitsidianakis 1 week ago
parent
commit
89940dd606
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS. GPG Key ID: 73627C2F690DF710
4 changed files with 75 additions and 17 deletions
  1. +1
    -0
      Cargo.lock
  2. +3
    -1
      Cargo.toml
  3. +23
    -9
      build.rs
  4. +48
    -7
      src/bin.rs

+ 1
- 0
Cargo.lock View File

@ -1061,6 +1061,7 @@ dependencies = [
"bincode",
"bitflags 1.2.1",
"crossbeam",
"flate2",
"futures",
"indexmap",
"libc",

+ 3
- 1
Cargo.toml View File

@ -57,11 +57,13 @@ svg_crate = { version = "0.8.0", optional = true, package = "svg" }
futures = "0.3.5"
async-task = "3.0.0"
num_cpus = "1.12.0"
flate2 = { version = "1.0.16", optional = true }
[build-dependencies]
syn = { version = "1.0.31", features = [] }
quote = "^1.0"
proc-macro2 = "1.0.18"
flate2 = { version = "1.0.16", optional = true }
[profile.release]
lto = "fat"
@ -80,7 +82,7 @@ sqlite3 = ["melib/sqlite3"]
smtp = ["melib/smtp"]
regexp = ["pcre2"]
dbus-notifications = ["notify-rust",]
cli-docs = []
cli-docs = ["flate2"]
svgscreenshot = ["svg_crate"]
gpgme = ["melib/gpgme"]

+ 23
- 9
build.rs View File

@ -37,6 +37,8 @@ fn main() {
]);
#[cfg(feature = "cli-docs")]
{
use flate2::Compression;
use flate2::GzBuilder;
const MANDOC_OPTS: &[&'static str] = &["-T", "utf8", "-I", "os=Generated by mandoc(1)"];
use std::env;
use std::fs::File;
@ -45,7 +47,7 @@ fn main() {
use std::process::Command;
let out_dir = env::var("OUT_DIR").unwrap();
let mut out_dir_path = Path::new(&out_dir).to_path_buf();
out_dir_path.push("meli.txt");
out_dir_path.push("meli.txt.gz");
let output = Command::new("mandoc")
.args(MANDOC_OPTS)
@ -54,11 +56,15 @@ fn main() {
.or_else(|_| Command::new("man").arg("-l").arg("docs/meli.1").output())
.unwrap();
let mut file = File::create(&out_dir_path).unwrap();
file.write_all(&output.stdout).unwrap();
let file = File::create(&out_dir_path).unwrap();
let mut gz = GzBuilder::new()
.comment(output.stdout.len().to_string().into_bytes())
.write(file, Compression::default());
gz.write_all(&output.stdout).unwrap();
gz.finish().unwrap();
out_dir_path.pop();
out_dir_path.push("meli.conf.txt");
out_dir_path.push("meli.conf.txt.gz");
let output = Command::new("mandoc")
.args(MANDOC_OPTS)
.arg("docs/meli.conf.5")
@ -70,11 +76,15 @@ fn main() {
.output()
})
.unwrap();
let mut file = File::create(&out_dir_path).unwrap();
file.write_all(&output.stdout).unwrap();
let file = File::create(&out_dir_path).unwrap();
let mut gz = GzBuilder::new()
.comment(output.stdout.len().to_string().into_bytes())
.write(file, Compression::default());
gz.write_all(&output.stdout).unwrap();
gz.finish().unwrap();
out_dir_path.pop();
out_dir_path.push("meli-themes.txt");
out_dir_path.push("meli-themes.txt.gz");
let output = Command::new("mandoc")
.args(MANDOC_OPTS)
.arg("docs/meli-themes.5")
@ -86,7 +96,11 @@ fn main() {
.output()
})
.unwrap();
let mut file = File::create(&out_dir_path).unwrap();
file.write_all(&output.stdout).unwrap();
let file = File::create(&out_dir_path).unwrap();
let mut gz = GzBuilder::new()
.comment(output.stdout.len().to_string().into_bytes())
.write(file, Compression::default());
gz.write_all(&output.stdout).unwrap();
gz.finish().unwrap();
}
}

+ 48
- 7
src/bin.rs View File

@ -150,7 +150,7 @@ fn parse_manpage(src: &str) -> Result {
use structopt::StructOpt;
#[derive(Debug)]
#[derive(Copy, Clone, Debug)]
/// Choose manpage
enum ManPages {
/// meli(1)
@ -206,6 +206,9 @@ enum SubCommand {
struct ManOpt {
#[structopt(default_value = "meli", possible_values=&["meli", "conf", "themes"], value_name="PAGE", parse(try_from_str = parse_manpage))]
page: ManPages,
/// If true, output text in stdout instead of spawning $PAGER.
#[structopt(long = "no-raw", alias = "no-raw", value_name = "bool")]
no_raw: Option<Option<bool>>,
}
fn main() {
@ -251,13 +254,51 @@ fn run_app(opt: Opt) -> Result<()> {
}
#[cfg(feature = "cli-docs")]
Some(SubCommand::Man(manopt)) => {
let _page = manopt.page;
const MANPAGES: [&'static str; 3] = [
include_str!(concat!(env!("OUT_DIR"), "/meli.txt")),
include_str!(concat!(env!("OUT_DIR"), "/meli.conf.txt")),
include_str!(concat!(env!("OUT_DIR"), "/meli-themes.txt")),
let ManOpt { page, no_raw } = manopt;
const MANPAGES: [&'static [u8]; 3] = [
include_bytes!(concat!(env!("OUT_DIR"), "/meli.txt.gz")),
include_bytes!(concat!(env!("OUT_DIR"), "/meli.conf.txt.gz")),
include_bytes!(concat!(env!("OUT_DIR"), "/meli-themes.txt.gz")),
];
println!("{}", MANPAGES[_page as usize]);
use flate2::bufread::GzDecoder;
use std::io::prelude::*;
let mut gz = GzDecoder::new(MANPAGES[page as usize]);
let mut v = String::with_capacity(
str::parse::<usize>(unsafe {
std::str::from_utf8_unchecked(gz.header().unwrap().comment().unwrap())
})
.expect(&format!(
"{:?} was not compressed with size comment header",
page
)),
);
gz.read_to_string(&mut v)?;
if let Some(no_raw) = no_raw {
match no_raw {
Some(true) => {}
None if (unsafe { libc::isatty(libc::STDOUT_FILENO) == 1 }) => {}
Some(false) | None => {
println!("{}", &v);
return Ok(());
}
}
} else {
if unsafe { libc::isatty(libc::STDOUT_FILENO) != 1 } {
println!("{}", &v);
return Ok(());
}
}
use std::process::{Command, Stdio};
let mut handle = Command::new(std::env::var("PAGER").unwrap_or("more".to_string()))
.stdin(Stdio::piped())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()?;
handle.stdin.take().unwrap().write_all(v.as_bytes())?;
handle.wait()?;
return Ok(());
}
#[cfg(not(feature = "cli-docs"))]

Loading…
Cancel
Save