mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 21:30:41 +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",
|
"pkg6depotd",
|
||||||
"pkg6dev",
|
"pkg6dev",
|
||||||
"pkg6repo",
|
"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