summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2020-10-13 20:42:39 +0200
committerMatthias Beyer <mail@beyermatthias.de>2020-10-13 20:54:46 +0200
commitc6c68d823e90ea0323e0fc39cd2621afe63a511f (patch)
tree5be56008dad5062bcaeff5966849237ce8793f6d
parent904f0bbebe7661a801414317aa2b6faf82752dd9 (diff)
Implement version / constraint parsing
-rw-r--r--Cargo.toml28
-rw-r--r--examples/packages/example_1/pkgA/pkg.toml2
-rw-r--r--src/package/dependency.rs77
-rw-r--r--src/package/version.rs96
4 files changed, 184 insertions, 19 deletions
diff --git a/Cargo.toml b/Cargo.toml
index d9f2889..6eb2511 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,19 +7,21 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-log = "0.3"
-tracing = "0.1"
-toml = "0.5"
-serde = "1"
-config = "0.9"
-anyhow = "1"
-getset = "0.1"
-walkdir = "2"
-resiter = "0.4"
-itertools = "0.9"
-clap-v3 = "3.0.0-beta.1"
-indicatif = "0.15"
-env_logger = "0.7"
+log = "0.3"
+tracing = "0.1"
+toml = "0.5"
+serde = "1"
+config = "0.9"
+anyhow = "1"
+getset = "0.1"
+walkdir = "2"
+resiter = "0.4"
+itertools = "0.9"
+clap-v3 = "3.0.0-beta.1"
+indicatif = "0.15"
+env_logger = "0.7"
+regex = "1"
+lazy_static = "1.4"
url = { version = "2", features = ["serde"] }
tokio = { version = "0.2", features = ["full"] }
diff --git a/examples/packages/example_1/pkgA/pkg.toml b/examples/packages/example_1/pkgA/pkg.toml
index 056a0f7..4d9d0bf 100644
--- a/examples/packages/example_1/pkgA/pkg.toml
+++ b/examples/packages/example_1/pkgA/pkg.toml
@@ -2,7 +2,7 @@ name = "pkgA"
version = "1.0.0"
[dependencies]
-runtime = [ "pkgB-1.0.0" ]
+runtime = [ "pkgB =1.0.0" ]
[source]
url = "http://somerandomthi.ng/foo/bar.tar.gz"
diff --git a/src/package/dependency.rs b/src/package/dependency.rs
index da3ac3a..14146c3 100644
--- a/src/package/dependency.rs
+++ b/src/package/dependency.rs
@@ -1,5 +1,8 @@
use std::result::Result as RResult;
use serde::Deserialize;
+use regex::Regex;
+use lazy_static::lazy_static;
+use anyhow::anyhow;
use crate::package::PackageName;
use crate::package::PackageVersionConstraint;
@@ -17,13 +20,81 @@ pub struct BuildDependency(String);
#[serde(transparent)]
pub struct Dependency(String);
+impl From<String> for Dependency {
+ fn from(s: String) -> Dependency {
+ Dependency(s)
+ }
+}
+
impl std::convert::TryInto<(PackageName, PackageVersionConstraint)> for Dependency {
type Error = anyhow::Error;
fn try_into(self) -> RResult<(PackageName, PackageVersionConstraint), Self::Error> {
- // TODO: Implement properly
- let v: Vec<_> = self.0.split("-").collect();
- Ok((PackageName::from(String::from(v[0])), PackageVersionConstraint::Any))
+ lazy_static! {
+ static ref RE: Regex = Regex::new("^(?P<name>[[:alpha:]]([[[:alnum:]]-_])*) (?P<version>([\\*=><])?[[:alnum:]]([[[:alnum:]][[:punct:]]])*)$").unwrap();
+ }
+
+ let caps = RE.captures(&self.0)
+ .ok_or_else(|| anyhow!("Could not parse into package name and package version constraint: '{}'", self.0))?;
+
+ let name = caps.name("name")
+ .ok_or_else(|| anyhow!("Could not parse name: '{}'", self.0))?;
+
+ let vers = caps.name("version")
+ .ok_or_else(|| anyhow!("Could not parse version: '{}'", self.0))?;
+
+ let constraint = PackageVersionConstraint::parse(vers.as_str())?;
+
+ Ok((PackageName::from(String::from(name.as_str())), constraint))
}
}
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::convert::TryInto;
+ use crate::package::PackageVersion;
+ use crate::package::PackageVersionConstraint;
+
+ //
+ // helper functions
+ //
+
+ fn name(s: &'static str) -> PackageName {
+ PackageName::from(String::from(s))
+ }
+
+ fn exact(s: &'static str) -> PackageVersionConstraint {
+ PackageVersionConstraint::Exact(PackageVersion::from(String::from(s)))
+ }
+
+ fn higher_as(s: &'static str) -> PackageVersionConstraint {
+ PackageVersionConstraint::HigherAs(PackageVersion::from(String::from(s)))
+ }
+
+ //
+ // tests
+ //
+
+ #[test]
+ fn test_dependency_conversion_1() {
+ let s = "vim =8.2";
+ let d = Dependency::from(String::from(s));
+
+ let (n, c) = d.try_into().unwrap();
+
+ assert_eq!(n, name("vim"));
+ assert_eq!(c, exact("8.2"));
+ }
+
+ #[test]
+ fn test_dependency_conversion_2() {
+ let s = "gtk15 >1b";
+ let d = Dependency::from(String::from(s));
+
+ let (n, c) = d.try_into().unwrap();
+
+ assert_eq!(n, name("gtk15"));
+ assert_eq!(c, higher_as("1b"));
+ }
+}
diff --git a/src/package/version.rs b/src/package/version.rs
index d6c385d..b326017 100644
--- a/src/package/version.rs
+++ b/src/package/version.rs
@@ -1,4 +1,5 @@
use serde::Deserialize;
+use anyhow::anyhow;
use anyhow::Result;
#[derive(Deserialize, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
@@ -17,7 +18,6 @@ impl From<String> for PackageVersion {
#[allow(unused)]
pub enum PackageVersionConstraint {
Any,
- Latest,
LowerAs(PackageVersion),
HigherAs(PackageVersion),
InRange(PackageVersion, PackageVersion),
@@ -28,13 +28,50 @@ impl PackageVersionConstraint {
pub fn matches(&self, v: &PackageVersion) -> Result<PackageVersionMatch> {
match self {
PackageVersionConstraint::Any => Ok(PackageVersionMatch::True),
- PackageVersionConstraint::Latest => Ok(PackageVersionMatch::Undecided),
PackageVersionConstraint::LowerAs(_vers) => Ok(PackageVersionMatch::Undecided), // TODO: Fix implementation
PackageVersionConstraint::HigherAs(_vers) => Ok(PackageVersionMatch::Undecided), // TODO: Fix implementation
PackageVersionConstraint::InRange(_vers1, _vers2) => Ok(PackageVersionMatch::Undecided), // TODO: Fix implementation
PackageVersionConstraint::Exact(vers) => Ok(PackageVersionMatch::from(*v == *vers)),
}
}
+
+ // TODO: Make this nice?
+ pub fn parse(s: &str) -> Result<Self> {
+ if s.is_empty() {
+ return Err(anyhow!("Cannot parse: '{}'", s))
+ }
+
+ let first_char = s.chars().next().ok_or_else(|| anyhow!("Failed to find first character: '{}'", s))?;
+ if first_char == '*' {
+ return Ok(PackageVersionConstraint::Any)
+ }
+
+ let v = s.chars().skip(1).collect::<String>();
+
+ if v.is_empty() {
+ return Err(anyhow!("Not a version: '{}'", v))
+ }
+
+ if first_char == '=' {
+ Ok(PackageVersionConstraint::Exact(PackageVersion::from(v)))
+ } else if first_char == '>' {
+ Ok(PackageVersionConstraint::HigherAs(PackageVersion::from(v)))
+ } else if first_char == '<' {
+ Ok(PackageVersionConstraint::LowerAs(PackageVersion::from(v)))
+ } else {
+ let mut iter = s.split("..");
+
+ let a = iter.next()
+ .map(String::from)
+ .ok_or_else(|| anyhow!("Trying to parse version range constraint failed: '{}'", s))?;
+
+ let b = iter.next()
+ .map(String::from)
+ .ok_or_else(|| anyhow!("Trying to parse version range constraint failed: '{}'", s))?;
+
+ Ok(PackageVersionConstraint::InRange(PackageVersion::from(a), PackageVersion::from(b)))
+ }
+ }
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
@@ -72,3 +109,58 @@ impl From<bool> for PackageVersionMatch {
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_parse_version_constraint_1() {
+ let s = "*";
+ let c = PackageVersionConstraint::parse(s).unwrap();
+ assert_eq!(c, PackageVersionConstraint::Any);
+ }
+
+ #[test]
+ fn test_parse_version_constraint_2() {
+ let s = "=1";
+ let c = PackageVersionConstraint::parse(s).unwrap();
+ assert_eq!(c, PackageVersionConstraint::Exact(PackageVersion::from(String::from("1"))));
+ }
+
+ #[test]
+ fn test_parse_version_constraint_3() {
+ let s = ">1";
+ let c = PackageVersionConstraint::parse(s).unwrap();
+ assert_eq!(c, PackageVersionConstraint::HigherAs(PackageVersion::from(String::from("1"))));
+ }
+
+ #[test]
+ fn test_parse_version_constraint_4() {
+ let s = "<1";
+ let c = PackageVersionConstraint::parse(s).unwrap();
+ assert_eq!(c, PackageVersionConstraint::LowerAs(PackageVersion::from(String::from("1"))));
+ }
+
+ #[test]
+ fn test_parse_version_constraint_5() {
+ let s = "=1.0.17";
+ let c = PackageVersionConstraint::parse(s).unwrap();
+ assert_eq!(c, PackageVersionConstraint::Exact(PackageVersion::from(String::from("1.0.17"))));
+ }
+
+ #[test]
+ fn test_parse_version_constraint_6() {
+ let s = "=1.0.17asejg";
+ let c = PackageVersionConstraint::parse(s).unwrap();
+ assert_eq!(c, PackageVersionConstraint::Exact(PackageVersion::from(String::from("1.0.17asejg"))));
+ }
+
+ #[test]
+ fn test_parse_version_constraint_7() {
+ let s = "=1-0B17-beta1247_commit_12653hasd";
+ let c = PackageVersionConstraint::parse(s).unwrap();
+ assert_eq!(c, PackageVersionConstraint::Exact(PackageVersion::from(String::from("1-0B17-beta1247_commit_12653hasd"))));
+ }
+}
+