Skip to content

Commit

Permalink
feat: read .gz manpages
Browse files Browse the repository at this point in the history
  • Loading branch information
ysthakur committed Aug 6, 2023
1 parent 347714c commit fcfa538
Show file tree
Hide file tree
Showing 6 changed files with 2,196 additions and 1,256 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Cargo.lock linguist-generated=true
flake.lock linguist-generated=true

tests/** linguist-generated=true
7 changes: 7 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ struct CLI {
#[arg(short, long)]
out: PathBuf,

/// Turn on verbose output
#[arg(short, long)]
verbose: bool,

/// Directories to exclude from search
#[arg(short = 'D', long, value_delimiter = ',')]
dirs_exclude: Option<Vec<PathBuf>>,
Expand Down Expand Up @@ -73,6 +77,9 @@ fn main() -> Result<()> {

if let Some(cmd) = &args.cmd {
if let Some(manpage) = man_completions::find_manpage(cmd, included) {
if args.verbose {
println!("Found manpage at {}", &manpage.display());
}
let parsed = parse_manpage_at_path(cmd, manpage)?;
let mut map = HashMap::new();
map.insert(cmd.to_string(), parsed);
Expand Down
25 changes: 22 additions & 3 deletions lib/src/parse/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
use std::collections::HashMap;
use std::{
collections::HashMap,
fs::File,
io::{BufReader, Read},
};

use flate2::bufread::GzDecoder;

use crate::Result;
use std::path::Path;
Expand All @@ -21,7 +27,19 @@ where
{
let path = manpage_path.as_ref();
match path.extension() {
Some(ext) => todo!(),
Some(ext) => {
if ext == "gz" {
let file = File::open(path)?;
let reader = BufReader::new(file);
let mut decoder = GzDecoder::new(reader);
let mut str = String::new();
// TODO this only works with UTF-8
decoder.read_to_string(&mut str)?;
Ok(str)
} else {
todo!()
}
}
None => todo!(),
}
}
Expand All @@ -34,5 +52,6 @@ where
}

pub fn parse_manpage_text(cmd_name: &str, text: &str) -> Result<CommandInfo> {
todo!()
let res = parse_man::parse(cmd_name, text)?;
Ok(res.unwrap())
}
27 changes: 21 additions & 6 deletions lib/src/parse/parse_man.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
use regex::Regex;
use regex::{Regex, RegexBuilder};

fn parse(s: &str) -> Option<()> {
match s.find("\nOPTIONS") {
Some(options_header) => {
let re = Regex::new("").unwrap();
use crate::result::Result;

use super::CommandInfo;

/// Regex to get the contents of a section with the given title
fn regex_for_section(title: &str) -> Regex {
RegexBuilder::new(&format!(r#"\.SH {title}(.*?)(\.SH|\z)"#))
.multi_line(true)
.dot_matches_new_line(true)
.build()
.unwrap()
}

pub fn parse(cmd_name: &str, page_text: &str) -> Result<Option<CommandInfo>> {
let re = regex_for_section(r#""OPTIONS""#);
match re.captures(page_text) {
Some(captures) => {
let content = captures.get(1).unwrap().as_str();
println!("{}", content);
todo!()
}
None => None
None => Ok(None),
}
}
4 changes: 2 additions & 2 deletions lib/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug, Error)]
pub enum Error {
#[error("could not parse manpage")]
ParseError(String),
#[error("parse error in {cmd}: {msg}")]
ParseError { cmd: String, msg: String },

#[error(transparent)]
IoError(#[from] std::io::Error),
Expand Down
Loading

0 comments on commit fcfa538

Please sign in to comment.