diff --git a/.idea/libips.iml b/.idea/ips.iml
similarity index 100%
rename from .idea/libips.iml
rename to .idea/ips.iml
diff --git a/.idea/modules.xml b/.idea/modules.xml
index c73cd4f..e425c83 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,7 +2,7 @@
-
+
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index 0d8dcc3..829a0be 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -24,6 +24,17 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
[[package]]
name = "autocfg"
version = "1.0.1"
@@ -44,6 +55,12 @@ dependencies = [
"rustc-demangle",
]
+[[package]]
+name = "bitflags"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+
[[package]]
name = "block-buffer"
version = "0.9.0"
@@ -66,6 +83,38 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+[[package]]
+name = "clap"
+version = "3.0.0-beta.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142"
+dependencies = [
+ "atty",
+ "bitflags",
+ "clap_derive",
+ "indexmap",
+ "lazy_static",
+ "os_str_bytes",
+ "strsim",
+ "termcolor",
+ "textwrap",
+ "unicode-width",
+ "vec_map",
+]
+
+[[package]]
+name = "clap_derive"
+version = "3.0.0-beta.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "cpuid-bool"
version = "0.1.2"
@@ -140,12 +189,52 @@ version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
+[[package]]
+name = "hashbrown"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
+
+[[package]]
+name = "heck"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
[[package]]
name = "keccak"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
[[package]]
name = "libc"
version = "0.2.90"
@@ -202,6 +291,12 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+[[package]]
+name = "os_str_bytes"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85"
+
[[package]]
name = "pkg6depotd"
version = "0.0.1-placeholder"
@@ -209,11 +304,41 @@ version = "0.0.1-placeholder"
[[package]]
name = "pkg6dev"
version = "0.0.1-placeholder"
+dependencies = [
+ "clap",
+ "failure",
+ "failure_derive",
+ "libips",
+]
[[package]]
name = "pkg6repo"
version = "0.0.1-placeholder"
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
[[package]]
name = "proc-macro2"
version = "1.0.24"
@@ -280,6 +405,12 @@ dependencies = [
"opaque-debug",
]
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
[[package]]
name = "syn"
version = "1.0.64"
@@ -303,18 +434,54 @@ dependencies = [
"unicode-xid",
]
+[[package]]
+name = "termcolor"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789"
+dependencies = [
+ "unicode-width",
+]
+
[[package]]
name = "typenum"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
+[[package]]
+name = "unicode-segmentation"
+version = "1.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
+
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+[[package]]
+name = "vec_map"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
+
[[package]]
name = "version_check"
version = "0.9.3"
@@ -326,3 +493,34 @@ name = "wasmparser"
version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/libips/Cargo.toml b/libips/Cargo.toml
index 6d64750..9c14e2e 100644
--- a/libips/Cargo.toml
+++ b/libips/Cargo.toml
@@ -21,4 +21,6 @@ failure = "0.1.8"
maplit = "0.1.6"
object = "0.23.0"
sha2 = "0.9.3"
-sha3 = "0.9.1"
\ No newline at end of file
+sha3 = "0.9.1"
+pest = "2.1.3"
+pest_derive = "2.1.0"
\ No newline at end of file
diff --git a/libips/src/actions/manifest.pest b/libips/src/actions/manifest.pest
new file mode 100644
index 0000000..0d1ea6c
--- /dev/null
+++ b/libips/src/actions/manifest.pest
@@ -0,0 +1,69 @@
+//
+// Created by intellij-pest on 2021-04-18
+// manifest
+// Author: Till Wegmueller
+//
+
+action_set = @{"set"}
+action_depend = @{"depend"}
+action_dir = @{"dir"}
+action_file = @{"file"}
+action_license = @{"license"}
+action_hardlink = @{"hardlink"}
+action_link = @{"link"}
+action_driver = @{"driver"}
+action_group = @{"group"}
+action_user = @{"user"}
+action_legacy = @{"legacy"}
+action_name = @{
+ action_set |
+ action_depend |
+ action_dir |
+ action_file |
+ action_license |
+ action_hardlink |
+ action_link |
+ action_driver |
+ action_group |
+ action_user |
+ action_legacy
+ }
+quoted_string = @{
+ "\""
+ ~ quoted_character*
+ ~ "\""
+}
+quoted_character = {
+ !"\"" // if the following text is not three apostrophes
+ ~ ANY // then consume one character
+}
+
+payload_character = {
+ !" " // if the following text is not three apostrophes
+ ~ ANY // then consume one character
+}
+
+comment_string = @{
+ "#"
+ ~ comment_character*
+ ~ NEWLINE
+}
+comment_character = {
+ !NEWLINE // if the following text is not three apostrophes
+ ~ ANY // then consume one character
+}
+
+transform_character = {
+ !">" // if the following text is not three apostrophes
+ ~ ANY // then consume one character
+}
+
+transform_action = @{ transform_character*}
+transform = {"" ~ " "? ~ transform_action ~ ">" }
+
+property_name = @{ ( ASCII_ALPHANUMERIC | "." | "_" )+ }
+property_value = @{ ( ASCII_ALPHANUMERIC | "/" | "," | "." | "_" | "-" | "%" | "*" | "@" | "(" | ")" | "$" | ":" | "+" )+ | quoted_string }
+payload = @{ payload_character* }
+property = { " "? ~ property_name ~ "=" ~ property_value }
+action = { action_name ~ " " ~ payload? ~ property+ ~ " "? ~ (NEWLINE | EOI) }
+manifest = { SOI ~ ( NEWLINE | comment_string | transform | action )+ ~ EOI }
diff --git a/libips/src/actions/mod.rs b/libips/src/actions/mod.rs
index fc78623..df66d5b 100644
--- a/libips/src/actions/mod.rs
+++ b/libips/src/actions/mod.rs
@@ -6,7 +6,7 @@
// Source https://docs.oracle.com/cd/E23824_01/html/E21796/pkg-5.html
use regex::{RegexSet, Regex};
-use std::collections::HashSet;
+use std::collections::{HashMap};
use std::fs::File as OsFile;
use std::io::BufRead;
use std::io::BufReader;
@@ -15,7 +15,10 @@ use crate::payload::Payload;
use std::clone::Clone;
use crate::digest::Digest;
use std::str::FromStr;
-use std::path::{Path, PathBuf};
+use std::path::{Path};
+use std::fmt;
+use pest::Parser;
+use crate::errors::Result;
pub trait FacetedAction {
// Add a facet to the action if the facet is already present the function returns false.
@@ -30,7 +33,7 @@ pub struct Action {
kind: ActionKind,
payload: Payload,
properties: Vec,
- facets: HashSet,
+ facets: HashMap,
}
impl Action {
@@ -39,22 +42,22 @@ impl Action {
kind,
payload: Payload::default(),
properties: Vec::new(),
- facets: HashSet::new(),
+ facets: HashMap::new(),
}
}
}
impl FacetedAction for Action {
fn add_facet(&mut self, facet: Facet) -> bool {
- return self.facets.insert(facet)
+ return self.facets.insert(facet.name.clone(), facet.clone()) == None
}
fn remove_facet(&mut self, facet: Facet) -> bool {
- return self.facets.remove(&facet)
+ return self.facets.remove(&facet.name) == Some(facet)
}
}
-#[derive(Debug, Default)]
+#[derive(Debug, Default, PartialEq)]
pub struct Dir {
pub path: String,
pub group: String,
@@ -62,22 +65,22 @@ pub struct Dir {
pub mode: String, //TODO implement as bitmask
pub revert_tag: String,
pub salvage_from: String,
- pub facets: HashSet,
+ pub facets: HashMap,
}
impl FacetedAction for Dir {
fn add_facet(&mut self, facet: Facet) -> bool {
- return self.facets.insert(facet)
+ return self.facets.insert(facet.name.clone(), facet.clone()) == None
}
fn remove_facet(&mut self, facet: Facet) -> bool {
- return self.facets.remove(&facet)
+ return self.facets.remove(&facet.name) == Some(facet)
}
}
-#[derive(Debug, Default)]
+#[derive(Debug, Default, PartialEq)]
pub struct File {
- pub payload: Payload,
+ pub payload: Option,
pub path: String,
pub group: String,
pub owner: String,
@@ -88,15 +91,17 @@ pub struct File {
pub revert_tag: String,
pub sys_attr: String,
pub properties: Vec,
- pub facets: HashSet,
+ pub facets: HashMap,
}
impl File {
- pub fn read_from_path(p: &Path) -> Result {
+ pub fn read_from_path(p: &Path) -> Result {
let mut f = File::default();
- f.payload = Payload::compute_payload(p)?;
match p.to_str() {
- Some(str) => f.path = str.to_string(),
+ Some(str) => {
+ f.path = str.to_string();
+ f.payload = Some(Payload::compute_payload(p)?);
+ },
None => return Err(FileError::FilePathIsNoStringError)?,
}
@@ -108,11 +113,11 @@ impl File {
impl FacetedAction for File {
fn add_facet(&mut self, facet: Facet) -> bool {
- return self.facets.insert(facet)
+ return self.facets.insert(facet.name.clone(), facet.clone()) == None
}
fn remove_facet(&mut self, facet: Facet) -> bool {
- return self.facets.remove(&facet)
+ return self.facets.remove(&facet.name) == Some(facet)
}
}
@@ -123,37 +128,37 @@ pub enum FileError {
}
//TODO implement multiple FMRI for require-any
-#[derive(Debug, Default)]
+#[derive(Debug, Default, PartialEq)]
pub struct Dependency {
pub fmri: String, //TODO make FMRI
pub dependency_type: String, //TODO make enum
pub predicate: String, //TODO make FMRI
pub root_image: String, //TODO make boolean
pub optional: Vec,
- pub facets: HashSet,
+ pub facets: HashMap,
}
impl FacetedAction for Dependency {
fn add_facet(&mut self, facet: Facet) -> bool {
- return self.facets.insert(facet)
+ return self.facets.insert(facet.name.clone(), facet.clone()) == None
}
fn remove_facet(&mut self, facet: Facet) -> bool {
- return self.facets.remove(&facet)
+ return self.facets.remove(&facet.name) == Some(facet)
}
}
-#[derive(Hash, Eq, PartialEq, Debug, Default)]
+#[derive(Hash, Eq, PartialEq, Debug, Default, Clone)]
pub struct Facet {
pub name: String,
pub value: String,
}
-#[derive(Debug, Default)]
+#[derive(Debug, Default, PartialEq)]
pub struct Attr {
pub key: String,
pub values: Vec,
- pub properties: HashSet,
+ pub properties: HashMap,
}
#[derive(Hash, Eq, PartialEq, Debug, Default)]
@@ -162,7 +167,7 @@ pub struct Property {
pub value: String,
}
-#[derive(Debug, Default)]
+#[derive(Debug, Default, PartialEq)]
pub struct Manifest {
pub attributes: Vec,
pub directories: Vec,
@@ -183,6 +188,10 @@ impl Manifest {
pub fn add_file(&mut self, f: File) {
self.files.push(f);
}
+
+ pub fn parse_file(&mut self, f: Path) -> Result {
+
+ }
}
#[derive(Debug)]
@@ -198,6 +207,7 @@ pub enum ActionKind {
Link,
Legacy,
Unknown{action: String},
+ Transform,
}
impl Default for ActionKind {
@@ -220,20 +230,27 @@ pub enum ManifestError {
},
}
-pub fn parse_manifest_file(filename: String) -> Result {
+#[derive(Parser)]
+#[grammar = "manifest.pest"]
+struct ManifestParser;
+
+pub fn parse_manifest_file(filename: String) -> Result {
let mut m = Manifest::new();
let f = OsFile::open(filename)?;
let file = BufReader::new(&f);
for (line_nr, line_read) in file.lines().enumerate() {
- handle_manifest_line(&mut m, line_read?.trim_start(), line_nr)?;
+ let line = line_read?;
+ if !line.starts_with("#") {
+ handle_manifest_line(&mut m, line.trim_start(), line_nr)?;
+ }
}
return Ok(m);
}
-pub fn parse_manifest_string(manifest: String) -> Result {
+pub fn parse_manifest_string(manifest: String) -> Result {
let mut m = Manifest::new();
for (line_nr, line) in manifest.lines().enumerate() {
handle_manifest_line(&mut m, line.trim_start(), line_nr)?;
@@ -241,7 +258,7 @@ pub fn parse_manifest_string(manifest: String) -> Result {
return Ok(m);
}
-fn handle_manifest_line(manifest: &mut Manifest, line: &str, line_nr: usize) -> Result<(), Error> {
+fn handle_manifest_line(manifest: &mut Manifest, line: &str, line_nr: usize) -> Result<()> {
match determine_action_kind(&line) {
ActionKind::Attr => {
manifest.attributes.push(parse_attr_action(String::from(line))?);
@@ -272,15 +289,20 @@ fn handle_manifest_line(manifest: &mut Manifest, line: &str, line_nr: usize) ->
}
ActionKind::Legacy => {
+ }
+ ActionKind::Transform => {
+
}
ActionKind::Unknown{action} => {
- Err(ManifestError::UnknownAction {action, line: line_nr})?;
+ if !action.is_empty() {
+ Err(ManifestError::UnknownAction {action, line: line_nr})?;
+ }
}
}
Ok(())
}
-fn add_facet_to_action(action: &mut T, facet_string: String, line: String, line_nr: usize) -> Result<(), ManifestError> {
+fn add_facet_to_action(action: &mut T, facet_string: String, line: String, line_nr: usize) -> Result<()> {
let mut facet_key = match facet_string.find(".") {
Some(idx) => {
facet_string.clone().split_off(idx+1)
@@ -325,6 +347,7 @@ fn determine_action_kind(line: &str) -> ActionKind {
"group" => ActionKind::Group,
"user" => ActionKind::User,
"legacy" => ActionKind::Legacy,
+ " ActionKind::Transform,
_ => ActionKind::Unknown{action: act},
}
}
@@ -333,17 +356,17 @@ fn clean_string_value(orig: &str) -> String {
return String::from(orig).trim_end().replace(&['"', '\\'][..], "")
}
-fn string_to_bool(orig: &str) -> Result {
+fn string_to_bool(orig: &str) -> Result {
match &String::from(orig).trim().to_lowercase()[..] {
"true" => Ok(true),
"false" => Ok(false),
"t" => Ok(true),
"f" => Ok(false),
- _ => Err(String::from("not a boolean like value"))
+ _ => Err(failure::err_msg("not a boolean like value"))
}
}
-fn parse_depend_action(line: String, line_nr: usize) -> Result {
+fn parse_depend_action(line: String, line_nr: usize) -> Result {
let mut act = Dependency::default();
let regex_set = RegexSet::new(&[
r#"([^ ]+)=([^"][^ ]+[^"])"#,
@@ -380,7 +403,7 @@ fn parse_depend_action(line: String, line_nr: usize) -> Result Result {
+fn parse_file_action(line: String, line_nr: usize) -> Result {
let mut act = File::default();
let regex_set = RegexSet::new(&[
r"file ([a-zA-Z0-9]+) ",
@@ -411,11 +434,11 @@ fn parse_file_action(line: String, line_nr: usize) -> Result {
"sysattr" => act.sys_attr = clean_string_value(&cap[val_cap_idx]),
"overlay" => act.overlay = match string_to_bool(&cap[val_cap_idx]) {
Ok(b) => b,
- Err(e) => return Err(ManifestError::InvalidAction {action: line, line: line_nr, message: e})?
- },
+ Err(e) => return Err(ManifestError::InvalidAction {action: line, line: line_nr, message: e?})?
+ },/
"preserve" => act.preserve = match string_to_bool(&cap[val_cap_idx]) {
Ok(b) => b,
- Err(e) => return Err(ManifestError::InvalidAction {action: line, line: line_nr, message: e})?
+ Err(e) => return Err(ManifestError::InvalidAction {action: line, line: line_nr, message: e?})?
},
"chash" | "pkg.content-hash" => act.payload.additional_identifiers.push(match Digest::from_str(clean_string_value(&cap[val_cap_idx]).as_str()) {
Ok(d) => d,
@@ -440,7 +463,7 @@ fn parse_file_action(line: String, line_nr: usize) -> Result {
Ok(act)
}
-fn parse_dir_action(line: String, line_nr: usize) -> Result {
+fn parse_dir_action(line: String, line_nr: usize) -> Result {
let mut act = Dir::default();
let regex_set = RegexSet::new(&[
r#"([^ ]+)=([^"][^ ]+[^"])"#,
@@ -480,7 +503,7 @@ fn parse_dir_action(line: String, line_nr: usize) -> Result {
Ok(act)
}
-fn parse_attr_action(line: String) -> Result {
+fn parse_attr_action(line: String) -> Result {
// Do a full line match to see if we can fast path this.
// This also catches values with spaces, that have not been properly escaped.
// Note: values with spaces must be properly escaped or the rest here will fail. Strings with
@@ -534,7 +557,7 @@ fn parse_attr_action(line: String) -> Result {
let value_space_regex = Regex::new(r#"value=([^"][^ ]+[^"])"#)?;
- let mut properties = HashSet::new();
+ let mut properties = HashMap::new();
let optionals_regex_no_quotes = Regex::new(r#"([^ ]+)=([^"][^ ]+[^"])"#)?;
let optionals_regex_quotes = Regex::new(r#"([^ ]+)=([^"][^ ]+[^"])"#)?;
@@ -552,7 +575,7 @@ fn parse_attr_action(line: String) -> Result {
continue;
}
- properties.insert(Property {
+ properties.insert(String::from(cap[1].trim()), Property {
key: String::from(cap[1].trim()),
value: String::from(cap[2].trim()),
});
@@ -563,7 +586,7 @@ fn parse_attr_action(line: String) -> Result {
continue;
}
- properties.insert(Property {
+ properties.insert(String::from(cap[1].trim()), Property {
key: String::from(cap[1].trim()),
value: String::from(cap[2].trim()),
});
diff --git a/libips/src/digest/mod.rs b/libips/src/digest/mod.rs
index 92b3327..3de2d59 100644
--- a/libips/src/digest/mod.rs
+++ b/libips/src/digest/mod.rs
@@ -9,7 +9,7 @@ use sha3::{Digest as Sha3Digest};
static DEFAULT_ALGORITHM: DigestAlgorithm = DigestAlgorithm::SHA512;
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Clone)]
pub enum DigestAlgorithm {
SHA1, //Default, sadly
SHA256, //sha256t
@@ -24,7 +24,7 @@ impl Default for DigestAlgorithm {
fn default() -> Self { DigestAlgorithm::SHA1 }
}
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Clone)]
pub enum DigestSource {
GzipCompressed,
GNUElf,
@@ -38,7 +38,7 @@ impl Default for DigestSource {
fn default() -> Self { DigestSource::PrimaryPayloadHash }
}
-#[derive(Debug, Default)]
+#[derive(Debug, Default, PartialEq, Clone)]
pub struct Digest {
pub hash: String,
pub algorithm: DigestAlgorithm,
@@ -116,6 +116,24 @@ impl Digest {
hash,
})
}
+
+ pub fn to_string(&self) -> String {
+ format!("{}:{}:{}", match self.source {
+ DigestSource::UncompressedFile => "file",
+ DigestSource::GzipCompressed => "gzip",
+ DigestSource::GNUElf => "gelf",
+ DigestSource::GNUElfUnsigned => "gelf.unsigned",
+ DigestSource::Unknown | _ => "unknown",
+ }, match self.algorithm {
+ DigestAlgorithm::SHA1 => "sha1",
+ DigestAlgorithm::SHA256 => "sha256t",
+ DigestAlgorithm::SHA512Half => "sha512t_256",
+ DigestAlgorithm::SHA512 => "sha512t",
+ DigestAlgorithm::SHA3256 => "sha3256t",
+ DigestAlgorithm::SHA3512Half => "sha3512t_256",
+ DigestAlgorithm::SHA3512 => "sha3512t",
+ }, self.hash)
+ }
}
#[derive(Debug, Fail)]
diff --git a/libips/src/lib.rs b/libips/src/lib.rs
index e5ec93e..ee57bc1 100644
--- a/libips/src/lib.rs
+++ b/libips/src/lib.rs
@@ -7,8 +7,18 @@ pub mod actions;
pub mod digest;
pub mod payload;
-#[macro_use] extern crate failure;
-#[macro_use] extern crate maplit;
+mod errors {
+ use failure::Error;
+ use std::result::Result as StdResult;
+
+ pub type Result = StdResult;
+}
+
+use errors::Result;
+
+#[macro_use]
+extern crate failure;
+extern crate maplit;
#[cfg(test)]
mod tests {
diff --git a/libips/src/payload/mod.rs b/libips/src/payload/mod.rs
index 77ab258..1eaa8db 100644
--- a/libips/src/payload/mod.rs
+++ b/libips/src/payload/mod.rs
@@ -8,7 +8,7 @@ use failure::Error;
use object::Object;
use std::path::Path;
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Clone)]
pub enum PayloadCompressionAlgorithm {
Gzip,
LZ4
@@ -18,7 +18,7 @@ impl Default for PayloadCompressionAlgorithm {
fn default() -> Self { PayloadCompressionAlgorithm::LZ4 }
}
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Clone)]
pub enum PayloadBits {
Independent,
Bits32,
@@ -29,7 +29,7 @@ impl Default for PayloadBits {
fn default() -> Self { PayloadBits::Independent }
}
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Clone)]
pub enum PayloadArchitecture {
NOARCH,
I386,
@@ -42,7 +42,7 @@ impl Default for PayloadArchitecture {
fn default() -> Self { PayloadArchitecture::NOARCH }
}
-#[derive(Debug, Default)]
+#[derive(Debug, Default, PartialEq, Clone)]
pub struct Payload {
pub primary_identifier: Digest,
pub additional_identifiers: Vec,
diff --git a/pkg6dev/Cargo.toml b/pkg6dev/Cargo.toml
index 7500933..da362a2 100644
--- a/pkg6dev/Cargo.toml
+++ b/pkg6dev/Cargo.toml
@@ -12,3 +12,7 @@ keywords = ["packaging", "illumos"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+libips = {path = "../libips"}
+failure = "0.1.8"
+failure_derive = "0.1.8"
+clap = "~3.0.0-beta.2"
\ No newline at end of file
diff --git a/pkg6dev/src/main.rs b/pkg6dev/src/main.rs
index e7a11a9..f9a5c67 100644
--- a/pkg6dev/src/main.rs
+++ b/pkg6dev/src/main.rs
@@ -1,3 +1,52 @@
-fn main() {
- println!("Hello, world!");
+#[macro_use]
+extern crate failure_derive;
+
+use clap::app_from_crate;
+use clap::{Arg, App};
+use libips::actions::{parse_manifest_file, File};
+
+mod errors {
+ use failure::Error;
+ use std::result::Result as StdResult;
+
+ pub type Result = StdResult;
+}
+
+use errors::Result;
+
+fn main() {
+ let opts = app_from_crate!().arg(Arg::new("proto_dir")
+ .short('p')
+ .long("proto-dir")
+ .value_name("PROTO_DIR")
+ .about("The Prototype directory where files are located after build")
+ .takes_value(true)//.required(true)
+ .default_value("../sample_data/pkgs/cups/build/prototype/i386")
+ ).subcommand(App::new("diff-manifests")
+ .about("shows differences between two manifests")
+ .arg(Arg::new("manifests")
+ .value_name("MANIFESTS")
+ .multiple(true)
+ .number_of_values(2)
+ )
+ ).get_matches();
+
+ let proto_dir = opts.value_of("proto_dir").expect("proto_dir is a mandatory variable. clap::Arg::required must be true");
+
+ //let manifests: Vec<_> = opts.values_of("manifests").unwrap().collect();
+
+ //let files = find_removed_files(String::from(&manifests[0]), String::from(&manifests[1])).unwrap();
+ let _ = find_removed_files(String::from("../sample_data/pkgs/cups/cups.p5m"), String::from("../sample_data/pkgs/cups/manifests/sample-manifest.p5m")).unwrap();
+
+}
+
+fn find_removed_files(manifest_file: String, other_manifest_file: String) -> Result> {
+ let manifest = parse_manifest_file(manifest_file)?;
+ let other_manifest = parse_manifest_file(other_manifest_file)?;
+
+ println!("{:#?}", manifest);
+ println!("{:#?}", other_manifest);
+
+
+ Ok(vec![File::default()])
}