-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 15cacb6
Showing
12 changed files
with
316 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/target | ||
Cargo.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "requirements" | ||
version = "0.1.0" | ||
authors = ["Baptiste Darthenay <[email protected]>"] | ||
description = "Python PIP requirements.txt parser" | ||
keywords = ["python", "pip", "requirements"] | ||
categories = ["parser-implementations"] | ||
readme = "README.md" | ||
edition = "2018" | ||
license = "MIT" | ||
repository = "https://github.com/batisteo/requirements" | ||
|
||
[lib] | ||
name = "requirements" | ||
path = "./src/lib.rs" | ||
|
||
[dependencies] | ||
regex = "^1" | ||
pest = "^2" | ||
pest_derive = "^2" | ||
globwalk = "^0.7" | ||
walkdir = "^2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# requirements | ||
|
||
Fast parser of requirement files (txt or in) | ||
|
||
## Usage | ||
__Soon…__ | ||
|
||
License: MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
use globwalk::GlobError; | ||
use requirements::{self, Requirement}; | ||
use std::{env, fs, path::Path}; | ||
use walkdir::DirEntry; | ||
|
||
fn find_req_files() -> Result<Vec<DirEntry>, GlobError> { | ||
let globwalker = globwalk::GlobWalkerBuilder::from_patterns(".", &["*req*.{txt,in}"]) | ||
.max_depth(4) | ||
.follow_links(true) | ||
.build()? | ||
.into_iter() | ||
.filter_map(Result::ok) | ||
.collect(); | ||
Ok(globwalker) | ||
} | ||
|
||
fn parse_requirements(path: &Path) -> () { | ||
let content = fs::read_to_string(&path).expect("Cannot read file"); | ||
let requirement_file: Vec<Requirement> = requirements::parse(&content).unwrap(); | ||
for requirement in requirement_file.into_iter() { | ||
println!("{:?}", requirement.line); | ||
} | ||
} | ||
|
||
fn show_parsing(args: &Vec<String>) -> () { | ||
if args.len() > 1 { | ||
parse_requirements(Path::new(&args[1])) | ||
} else { | ||
for path in find_req_files().unwrap() { | ||
parse_requirements(&path.path()) | ||
} | ||
} | ||
} | ||
|
||
fn main() { | ||
let args: Vec<String> = env::args().collect(); | ||
show_parsing(&args); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use crate::Rule; | ||
use std::fmt; | ||
|
||
#[derive(Debug)] | ||
pub enum Comparison { | ||
LessThan, | ||
LessThanOrEqual, | ||
NotEqual, | ||
Equal, | ||
GreaterThanOrEqual, | ||
GreaterThan, | ||
CompatibleRelease, | ||
ArbitraryEqual, | ||
} | ||
|
||
impl Comparison { | ||
pub fn from_rule(rule: Rule) -> Comparison { | ||
use Comparison::*; | ||
match rule { | ||
Rule::less_than => LessThan, | ||
Rule::less_than_or_equal => LessThanOrEqual, | ||
Rule::not_equal => NotEqual, | ||
Rule::equal => Equal, | ||
Rule::greater_than_or_equal => GreaterThanOrEqual, | ||
Rule::greater_than => GreaterThan, | ||
Rule::compatible_release => CompatibleRelease, | ||
Rule::arbitrary_equal => ArbitraryEqual, | ||
_ => ArbitraryEqual, | ||
} | ||
} | ||
} | ||
|
||
impl fmt::Display for Comparison { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
use Comparison::*; | ||
let sign = match self { | ||
LessThan => "<", | ||
LessThanOrEqual => "<=", | ||
NotEqual => "!=", | ||
Equal => "==", | ||
GreaterThanOrEqual => ">=", | ||
GreaterThan => ">", | ||
CompatibleRelease => "~=", | ||
ArbitraryEqual => "===", | ||
}; | ||
write!(f, "{}", sign) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pub mod comparison; | ||
pub mod vcs; | ||
|
||
pub use comparison::Comparison; | ||
pub use vcs::VersionControlSystem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#[derive(Debug)] | ||
pub enum VersionControlSystem { | ||
Git, | ||
Mercurial, | ||
Subversion, | ||
Bazaar, | ||
Unknown, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
//! Fast parser of requirement files (txt or in) | ||
//! | ||
//! # Usage | ||
//! __Soon…__ | ||
|
||
#[macro_use] | ||
extern crate pest_derive; | ||
|
||
mod enums; | ||
|
||
use enums::{Comparison, VersionControlSystem}; | ||
use pest::error::Error; | ||
use pest::iterators::Pair; | ||
use pest::Parser; | ||
use std::path::Path; | ||
|
||
impl VersionControlSystem { | ||
pub fn _from_rule(rule: Rule) -> VersionControlSystem { | ||
use VersionControlSystem::*; | ||
match rule { | ||
Rule::git => Git, | ||
Rule::hg => Mercurial, | ||
Rule::svn => Subversion, | ||
Rule::bzr => Bazaar, | ||
_ => Unknown, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Parser)] | ||
#[grammar = "requirements.pest"] | ||
pub struct RequirementParser; | ||
|
||
#[derive(Debug)] | ||
pub struct Requirement<'a> { | ||
pub line: &'a str, | ||
pub editable: bool, | ||
pub name: &'a str, | ||
pub comment: Option<&'a str>, | ||
pub specifier: bool, | ||
pub vcs: Option<VersionControlSystem>, | ||
pub uri: Option<&'a Path>, | ||
pub subdirectory: Option<&'a str>, | ||
pub path: Option<&'a Path>, | ||
pub hash_name: Option<&'a str>, | ||
pub hash: Option<&'a str>, | ||
pub revision: Option<&'a str>, | ||
pub extras: Vec<&'a str>, | ||
pub specs: Vec<(Comparison, &'a str)>, | ||
pub extra_index_url: &'a str, | ||
} | ||
|
||
impl Requirement<'_> { | ||
fn new<'a>() -> Requirement<'a> { | ||
Requirement { | ||
line: "", | ||
name: "", | ||
specs: vec![], | ||
extras: vec![], | ||
comment: None, | ||
specifier: true, | ||
editable: false, | ||
uri: None, | ||
subdirectory: None, | ||
path: None, | ||
hash_name: None, | ||
hash: None, | ||
revision: None, | ||
vcs: None, | ||
extra_index_url: "", | ||
} | ||
} | ||
} | ||
|
||
fn parse_version(pair: Pair<Rule>) -> (Comparison, &str) { | ||
let mut version = pair.into_inner(); | ||
let comparison = Comparison::from_rule(version.next().unwrap().as_rule()); | ||
let number = version.next().unwrap().as_str(); | ||
(comparison, number) | ||
} | ||
|
||
fn parse_package(parsed: Pair<'_, Rule>) -> Requirement<'_> { | ||
let mut package = Requirement::new(); | ||
for line in parsed.into_inner() { | ||
package.line = line.as_str(); | ||
for pair in line.into_inner() { | ||
match &pair.as_rule() { | ||
Rule::name => package.name = pair.as_str(), | ||
Rule::version => package.specs.push(parse_version(pair)), | ||
Rule::extras => { | ||
package.extras = pair.into_inner().map(|extra| extra.as_str()).collect() | ||
} | ||
Rule::comment => { | ||
package.comment = { | ||
let comment = pair.into_inner().next().unwrap().as_str(); | ||
if comment.is_empty() { | ||
None | ||
} else { | ||
Some(comment) | ||
} | ||
} | ||
} | ||
Rule::extra_index_url => package.extra_index_url = pair.as_str(), | ||
_ => (), | ||
} | ||
} | ||
} | ||
package | ||
} | ||
|
||
pub fn parse(unparsed_file: &str) -> Result<Vec<Requirement>, Error<Rule>> { | ||
let requirement_file = RequirementParser::parse(Rule::requirement_file, &unparsed_file)? | ||
.next() | ||
.unwrap(); | ||
|
||
// copy_of_requirement_file = requirement_file.copy(); | ||
let requirements: Vec<Requirement> = requirement_file | ||
.into_inner() | ||
.filter(|pair| pair.as_rule() == Rule::line) | ||
.map(parse_package) | ||
.collect(); | ||
|
||
// let metas: Vec<Requirement> = copy_of_requirement_file | ||
// .into_inner() | ||
// .filter(|pair| pair.as_rule() == Rule::meta) | ||
// .map(parse_package) | ||
// .collect(); | ||
// println!("{:?}", metas); | ||
Ok(requirements) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
WHITESPACE = _{ " " | "\t" } | ||
|
||
requirement_file = { SOI ~ ((line)? ~ NEWLINE)* } | ||
|
||
// meta = { meta | requirement } | ||
line = { extra_index_url | comment | package | path } | ||
|
||
package = { name ~ extras? ~ (version | ",")* ~ comment? } | ||
name = @{ LETTER ~ chars } | ||
extras = { "[" ~ (extra | ",")+ ~ "]" } | ||
extra = @{ chars } | ||
version = { comparison ~ number } | ||
|
||
path = { editable? ~ chars } | ||
editable = { ("-e" | "--editable") } | ||
|
||
comment = { "#" ~ some_text } | ||
|
||
extra_index_url = { "--extra-index-url" ~ url } | ||
|
||
|
||
comparison = _{ less_than | less_than_or_equal | not_equal | equal | greater_than_or_equal | greater_than | compatible_release | arbitrary_equal } | ||
less_than = { "<" } | ||
less_than_or_equal = { "<=" } | ||
not_equal = { "!=" } | ||
equal = { "==" } | ||
greater_than_or_equal = { ">=" } | ||
greater_than = { ">" } | ||
compatible_release = { "~=" } | ||
arbitrary_equal = { "===" } | ||
|
||
vcs = _{ git | hg | svn | bzr } | ||
git = { "git" } | ||
hg = { "hg" } | ||
svn = { "svn" } | ||
bzr = { "bzr" } | ||
|
||
chars = _{ (ASCII_ALPHANUMERIC | "_" | "-")+ } | ||
version_char = _{ (ASCII_ALPHANUMERIC | ".") } | ||
number = @{ version_char+ } | ||
some_char = _{ (LETTER | NUMBER | PUNCTUATION | SYMBOL) } | ||
some_text = { some_char* } | ||
url = @{ "http" ~ "s"? ~ "://" ~ some_char+ } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
aiohttp | ||
passlib[argon2,chacha] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Example requirement file | ||
--extra-index-url https://pypi.example.com/pypi | ||
|
||
aiohttp | ||
black==19.10b0 | ||
chardet # upgrade at will | ||
Django>=2,<3 | ||
-e editable_package | ||
passlib[argon2,chacha] |