mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 13:20:42 +00:00
Add userland library for things related to oi userland
This commit is contained in:
parent
4fd068ac5f
commit
37d7d8ee08
6 changed files with 1124 additions and 4 deletions
901
Cargo.lock
generated
901
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -5,6 +5,7 @@ members = [
|
|||
"pkg6depotd",
|
||||
"pkg6dev",
|
||||
"pkg6repo",
|
||||
"userland",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
17
userland/Cargo.toml
Normal file
17
userland/Cargo.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "userland"
|
||||
version = "0.1.0"
|
||||
authors = ["Till Wegmueller <toasterson@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
failure = "0.1.8"
|
||||
pest_derive = "2.1.0"
|
||||
maplit = "0.1.6"
|
||||
pest = "2.1.0"
|
||||
reqwest = { version = "0.11", features = ["blocking", "json"] }
|
||||
semver = "0.11.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
109
userland/src/lib.rs
Normal file
109
userland/src/lib.rs
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
pub mod repology;
|
||||
|
||||
extern crate pest;
|
||||
#[macro_use] extern crate pest_derive;
|
||||
#[macro_use] extern crate failure;
|
||||
#[macro_use] extern crate serde;
|
||||
extern crate maplit;
|
||||
|
||||
mod errors {
|
||||
use failure::Error;
|
||||
use std::result::Result as StdResult;
|
||||
|
||||
pub type Result<T> = StdResult<T, Error>;
|
||||
}
|
||||
|
||||
use errors::Result;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::read_to_string;
|
||||
use pest::iterators::{Pair, Pairs};
|
||||
use std::path::Path;
|
||||
use pest::Parser;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "makefile.pest"]
|
||||
struct MakefileParser;
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone)]
|
||||
pub struct Makefile {
|
||||
pub variables: HashMap<String, Vec<String>>,
|
||||
// pub includes: Vec<String>,
|
||||
// pub targets: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Makefile {
|
||||
pub fn parse_file(path: &Path) -> Result<Self> {
|
||||
let content = read_to_string(path)?;
|
||||
parse_string(content)
|
||||
}
|
||||
|
||||
pub fn parse_string(content: String) -> Result<Self> {
|
||||
parse_string(content)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_string(content: String) -> Result<Makefile> {
|
||||
let mut m = Makefile::default();
|
||||
|
||||
let makefile_pair = MakefileParser::parse(Rule::makefile, &content)?;
|
||||
|
||||
for p in makefile_pair {
|
||||
match p.as_rule() {
|
||||
Rule::makefile => {
|
||||
parse_makefile(p.into_inner(), &mut m)?;
|
||||
}
|
||||
_ => panic!("unexpected rule {:?} inside pair expected manifest", p.as_rule()),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(m)
|
||||
}
|
||||
|
||||
fn parse_makefile(pairs: Pairs<crate::Rule>, m: &mut Makefile) -> Result<()> {
|
||||
for p in pairs {
|
||||
match p.as_rule() {
|
||||
Rule::variable => {
|
||||
parse_variable(p.into_inner(), m)?;
|
||||
}
|
||||
Rule::comment_string => (),
|
||||
Rule::include => (),
|
||||
Rule::target => (),
|
||||
Rule::EOI => (),
|
||||
_ => panic!("unexpected rule {:?} inside makefile rule expected variable, comment, NEWLINE, include, target", p.as_rule()),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_variable(variable_pair: Pairs<crate::Rule>, m: &mut Makefile) -> Result<()> {
|
||||
let mut var = (String::new(), Vec::<String>::new());
|
||||
for p in variable_pair {
|
||||
match p.as_rule() {
|
||||
Rule::variable_name => {
|
||||
var.0 = p.as_str().to_string();
|
||||
}
|
||||
Rule::variable_set => (),
|
||||
Rule::variable_add => {
|
||||
if m.variables.contains_key(&var.0) {
|
||||
var.1 = m.variables.get(&var.0).unwrap().clone()
|
||||
}
|
||||
}
|
||||
Rule::variable_value => {
|
||||
var.1.push(p.as_str().to_string());
|
||||
}
|
||||
_ => panic!("unexpected rule {:?} inside makefile rule expected variable_name, variable_set, variable_add, variable_value", p.as_rule()),
|
||||
}
|
||||
}
|
||||
m.variables.insert(var.0, var.1);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert_eq!(2 + 2, 4);
|
||||
}
|
||||
}
|
||||
43
userland/src/makefile.pest
Normal file
43
userland/src/makefile.pest
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// Created by intellij-pest on 2021-04-25
|
||||
// makefile
|
||||
// Author: Till Wegmueller <till.wegmueller@openflowlabs.com>
|
||||
//
|
||||
|
||||
WHITESPACE = _{ " " | "\t" }
|
||||
|
||||
comment_string = _{
|
||||
"#"
|
||||
~ comment_character*
|
||||
~ NEWLINE
|
||||
}
|
||||
comment_character = _{
|
||||
!NEWLINE // if the following text is not three apostrophes
|
||||
~ ANY // then consume one character
|
||||
}
|
||||
|
||||
variable_name_character = { UPPERCASE | ASCII_DIGIT | "_" }
|
||||
variable_name = @{ variable_name_character* }
|
||||
variable_value_character = {
|
||||
!NEWLINE
|
||||
~ ANY
|
||||
}
|
||||
variable_value = @{ variable_value_character* }
|
||||
|
||||
variable_set = { "=" }
|
||||
variable_add = { "+=" }
|
||||
|
||||
variable = { variable_name ~ ( variable_set | variable_add ) ~ variable_value? }
|
||||
|
||||
target_character = {
|
||||
!":"
|
||||
~ ANY
|
||||
}
|
||||
|
||||
target_name = { target_character+ }
|
||||
|
||||
target = { target_name ~ ":" ~ variable_value }
|
||||
|
||||
include = { "include" ~ variable_value }
|
||||
|
||||
makefile = { SOI ~ (NEWLINE | comment_string | variable | include | target )+ ~ EOI }
|
||||
57
userland/src/repology.rs
Normal file
57
userland/src/repology.rs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
extern crate reqwest;
|
||||
|
||||
use reqwest::*;
|
||||
use crate::errors::Result as EResult;
|
||||
use semver::Version;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
const BASE_URL: &str = "https://repology.org/api/v1/";
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RepologyClient {
|
||||
client: reqwest::Client,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Package {
|
||||
repo: String,
|
||||
name: Option<String>,
|
||||
version: String,
|
||||
sub_repo: Option<String>,
|
||||
orig_version: Option<String>,
|
||||
status: Option<String>,
|
||||
summary: Option<String>,
|
||||
family: Option<String>,
|
||||
categories: Option<Vec<String>>,
|
||||
licenses: Option<Vec<String>>,
|
||||
maintainers: Option<Vec<String>>,
|
||||
www: Option<Vec<String>>,
|
||||
downloads: Option<Vec<String>>
|
||||
}
|
||||
|
||||
pub fn project(package: &str) -> Result<Vec<Package>> {
|
||||
|
||||
let url = Url::parse(&format!("{}/project/{}",BASE_URL, package)).unwrap();
|
||||
|
||||
let json = reqwest::blocking::get(url)?
|
||||
.json::<Vec<Package>>()?;
|
||||
|
||||
return Ok(json);
|
||||
}
|
||||
|
||||
pub fn find_newest_version(package: &str) -> EResult<String> {
|
||||
let pkgs = project(package)?;
|
||||
let version_res: EResult<Vec<Version>> = pkgs.iter().map(|p| -> EResult<Version> {
|
||||
let v = Version::parse(&p.version);
|
||||
if v.is_ok() {
|
||||
return Ok(v?);
|
||||
}
|
||||
Ok(Version::new(0,0,1))
|
||||
}).collect();
|
||||
|
||||
let mut versions = version_res?;
|
||||
|
||||
versions.sort();
|
||||
|
||||
Ok(versions.last().unwrap().to_string())
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue