mirror of
https://github.com/orhun/systeroid
synced 2024-07-21 10:25:00 +00:00
feat(parser): add a mechanism for checking the existence of required files
This commit is contained in:
parent
7d1f85a90e
commit
f7f323d3af
|
@ -10,6 +10,7 @@ lazy_static! {
|
|||
pub static ref PARSERS: Vec<Parser<'static>> = vec![
|
||||
Parser {
|
||||
glob_path: "admin-guide/sysctl/*.rst",
|
||||
required_files: &["kernel.rst"],
|
||||
regex: RegexBuilder::new("^\n([a-z].*)\n[=,-]{2,}+\n\n")
|
||||
.multi_line(true)
|
||||
.build()
|
||||
|
@ -17,6 +18,7 @@ lazy_static! {
|
|||
},
|
||||
Parser {
|
||||
glob_path: "networking/*-sysctl.rst",
|
||||
required_files: &["ip-sysctl.rst"],
|
||||
regex: RegexBuilder::new("^([a-zA-Z0-9_/-]+[ ]-[ ][a-zA-Z].*)$")
|
||||
.multi_line(true)
|
||||
.build()
|
||||
|
|
|
@ -4,7 +4,7 @@ use thiserror::Error as ThisError;
|
|||
#[derive(Debug, ThisError)]
|
||||
pub enum Error {
|
||||
/// Error that may occur during I/O operations.
|
||||
#[error("IO error: `{0}`")]
|
||||
#[error("IO error: '{0}'")]
|
||||
IoError(#[from] std::io::Error),
|
||||
/// Error that may occur due to invalid UTF-8 strings.
|
||||
#[error("non-UTF-8 string")]
|
||||
|
@ -12,10 +12,13 @@ pub enum Error {
|
|||
/// Error that may occur when the capture group does not exist.
|
||||
#[error("capture group does not exist")]
|
||||
CaptureError,
|
||||
/// Error that may occur when a required file for parsing does not exist.
|
||||
#[error("required file missing: '{0}'")]
|
||||
MissingFileError(String),
|
||||
/// Error that may occur while traversing paths using a glob pattern.
|
||||
#[error("glob error: `{0}`")]
|
||||
#[error("glob error: '{0}'")]
|
||||
GlobError(#[from] globwalk::GlobError),
|
||||
/// Error that may occur during the compilation of a regex.
|
||||
#[error("regex error: `{0}`")]
|
||||
#[error("regex error: '{0}'")]
|
||||
RegexError(#[from] regex::Error),
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::document::{Document, Paragraph};
|
||||
use crate::error::Error;
|
||||
use crate::reader;
|
||||
use globwalk::DirEntry;
|
||||
use regex::{Captures, Regex, RegexBuilder};
|
||||
use std::path::Path;
|
||||
use std::result::Result as StdResult;
|
||||
|
@ -13,15 +14,22 @@ use std::result::Result as StdResult;
|
|||
pub struct Parser<'a> {
|
||||
/// Glob pattern to specify the files to parse.
|
||||
pub glob_path: &'a str,
|
||||
/// Files to check during path traversal.
|
||||
pub required_files: &'a [&'a str],
|
||||
/// Regular expression to use for parsing.
|
||||
pub regex: Regex,
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
/// Constructs a new instance.
|
||||
pub fn new(glob_path: &'a str, regex: &'a str) -> Result<Self, Error> {
|
||||
pub fn new(
|
||||
glob_path: &'a str,
|
||||
required_files: &'a [&'a str],
|
||||
regex: &'a str,
|
||||
) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
glob_path,
|
||||
required_files,
|
||||
regex: RegexBuilder::new(regex).multi_line(true).build()?,
|
||||
})
|
||||
}
|
||||
|
@ -29,14 +37,23 @@ impl<'a> Parser<'a> {
|
|||
/// Parses the files in the given base path and returns the documents.
|
||||
pub fn parse(&self, base_path: &Path) -> Result<Vec<Document>, Error> {
|
||||
let mut documents = Vec::new();
|
||||
for file in globwalk::glob(
|
||||
let glob_files = globwalk::glob(
|
||||
base_path
|
||||
.join(self.glob_path)
|
||||
.to_str()
|
||||
.ok_or(Error::Utf8Error)?,
|
||||
)?
|
||||
.filter_map(StdResult::ok)
|
||||
{
|
||||
.collect::<Vec<DirEntry>>();
|
||||
self.required_files.iter().try_for_each(|file_name| {
|
||||
glob_files
|
||||
.iter()
|
||||
.find(|file| file.file_name().to_str() == Some(file_name))
|
||||
.map(drop)
|
||||
.ok_or_else(|| Error::MissingFileError(file_name.to_string()))
|
||||
})?;
|
||||
for file in glob_files {
|
||||
println!("{:?}", file);
|
||||
let input = reader::read_to_string(file.path())?;
|
||||
let capture_group = self
|
||||
.regex
|
||||
|
@ -59,7 +76,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_document_parser() -> Result<(), Error> {
|
||||
let base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
let parser = Parser::new("Cargo.*", r#"^(\[package\])\n"#)?;
|
||||
let parser = Parser::new("Cargo.*", &["Cargo.toml"], r#"^(\[package\])\n"#)?;
|
||||
let mut documents = parser.parse(base_path.as_path())?;
|
||||
|
||||
assert!(documents[0].paragraphs[0]
|
||||
|
|
|
@ -5,7 +5,7 @@ use systeroid_parser::parser::Parser;
|
|||
#[test]
|
||||
fn test_parser() -> Result<(), Error> {
|
||||
let base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
let parser = Parser::new("src/*.rs", r#"^(#\[cfg\(test\)\])$\n"#)?;
|
||||
let parser = Parser::new("src/*.rs", &["lib.rs"], r#"^(#\[cfg\(test\)\])$\n"#)?;
|
||||
let documents = parser.parse(base_path.as_path())?;
|
||||
|
||||
assert!(documents
|
||||
|
|
|
@ -40,7 +40,7 @@ impl<'a> App<'a> {
|
|||
fn fetch_documentation(&mut self, kernel_docs: &Path) -> Result<()> {
|
||||
if !kernel_docs.exists() {
|
||||
eprintln!(
|
||||
"warning: Linux kernel documentation is not found in path: {:?}",
|
||||
"warning: linux kernel documentation is not found in path: {:?}",
|
||||
kernel_docs.to_string_lossy()
|
||||
);
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ impl<'a> App<'a> {
|
|||
}
|
||||
Err(e) => {
|
||||
if !pager.is_empty() {
|
||||
eprintln!("error: `pager error: {}`", e);
|
||||
eprintln!("pager error: `{}`", e);
|
||||
}
|
||||
fallback_to_default = true;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ fn main() {
|
|||
match systeroid::run(args) {
|
||||
Ok(_) => process::exit(0),
|
||||
Err(e) => {
|
||||
eprintln!("error: `{}`", e);
|
||||
eprintln!("{}", e);
|
||||
process::exit(1)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue