cli-docs: compress included text

jmap-eventsource
Manos Pitsidianakis 2020-10-17 20:50:29 +03:00
parent b69bc219c3
commit 89940dd606
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 75 additions and 17 deletions

1
Cargo.lock generated
View File

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

View File

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

View File

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

View File

@ -150,7 +150,7 @@ fn parse_manpage(src: &str) -> Result<ManPages> {
use structopt::StructOpt; use structopt::StructOpt;
#[derive(Debug)] #[derive(Copy, Clone, Debug)]
/// Choose manpage /// Choose manpage
enum ManPages { enum ManPages {
/// meli(1) /// meli(1)
@ -206,6 +206,9 @@ enum SubCommand {
struct ManOpt { struct ManOpt {
#[structopt(default_value = "meli", possible_values=&["meli", "conf", "themes"], value_name="PAGE", parse(try_from_str = parse_manpage))] #[structopt(default_value = "meli", possible_values=&["meli", "conf", "themes"], value_name="PAGE", parse(try_from_str = parse_manpage))]
page: ManPages, 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() { fn main() {
@ -251,13 +254,51 @@ fn run_app(opt: Opt) -> Result<()> {
} }
#[cfg(feature = "cli-docs")] #[cfg(feature = "cli-docs")]
Some(SubCommand::Man(manopt)) => { Some(SubCommand::Man(manopt)) => {
let _page = manopt.page; let ManOpt { page, no_raw } = manopt;
const MANPAGES: [&'static str; 3] = [ const MANPAGES: [&'static [u8]; 3] = [
include_str!(concat!(env!("OUT_DIR"), "/meli.txt")), include_bytes!(concat!(env!("OUT_DIR"), "/meli.txt.gz")),
include_str!(concat!(env!("OUT_DIR"), "/meli.conf.txt")), include_bytes!(concat!(env!("OUT_DIR"), "/meli.conf.txt.gz")),
include_str!(concat!(env!("OUT_DIR"), "/meli-themes.txt")), 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(()); return Ok(());
} }
#[cfg(not(feature = "cli-docs"))] #[cfg(not(feature = "cli-docs"))]