mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 21:30:41 +00:00
First CI/CD feature
This commit is contained in:
parent
499e5aee59
commit
a4b998d9d4
2 changed files with 124 additions and 34 deletions
|
|
@ -55,7 +55,7 @@ impl FacetedAction for Action {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq)]
|
#[derive(Debug, Default, PartialEq, Clone)]
|
||||||
pub struct Dir {
|
pub struct Dir {
|
||||||
pub path: String,
|
pub path: String,
|
||||||
pub group: String,
|
pub group: String,
|
||||||
|
|
@ -106,7 +106,7 @@ impl FacetedAction for Dir {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq)]
|
#[derive(Debug, Default, PartialEq, Clone)]
|
||||||
pub struct File {
|
pub struct File {
|
||||||
pub payload: Option<Payload>,
|
pub payload: Option<Payload>,
|
||||||
pub path: String,
|
pub path: String,
|
||||||
|
|
@ -137,6 +137,15 @@ impl File {
|
||||||
|
|
||||||
Ok(f)
|
Ok(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_original_path(&self) ->Option<String> {
|
||||||
|
for p in &self.properties {
|
||||||
|
if p.key.as_str() == "original-path" {
|
||||||
|
return Some(p.value.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Action> for File {
|
impl From<Action> for File {
|
||||||
|
|
@ -155,7 +164,7 @@ impl From<Action> for File {
|
||||||
} else {
|
} else {
|
||||||
file.properties.push(Property{
|
file.properties.push(Property{
|
||||||
key: "original-path".to_string(),
|
key: "original-path".to_string(),
|
||||||
value: act.payload_string.replace("\"", "")
|
value: act.payload_string.replace("\"", "").replace("\\", "")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -218,7 +227,7 @@ pub enum FileError {
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO implement multiple FMRI for require-any
|
//TODO implement multiple FMRI for require-any
|
||||||
#[derive(Debug, Default, PartialEq)]
|
#[derive(Debug, Default, PartialEq, Clone)]
|
||||||
pub struct Dependency {
|
pub struct Dependency {
|
||||||
pub fmri: String, //TODO make FMRI
|
pub fmri: String, //TODO make FMRI
|
||||||
pub dependency_type: String, //TODO make enum
|
pub dependency_type: String, //TODO make enum
|
||||||
|
|
@ -283,7 +292,7 @@ impl Facet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq)]
|
#[derive(Debug, Default, PartialEq, Clone)]
|
||||||
pub struct Attr {
|
pub struct Attr {
|
||||||
pub key: String,
|
pub key: String,
|
||||||
pub values: Vec<String>,
|
pub values: Vec<String>,
|
||||||
|
|
@ -383,7 +392,7 @@ pub struct Property {
|
||||||
pub value: String,
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq)]
|
#[derive(Debug, Default, PartialEq, Clone)]
|
||||||
pub struct Manifest {
|
pub struct Manifest {
|
||||||
pub attributes: Vec<Attr>,
|
pub attributes: Vec<Attr>,
|
||||||
pub directories: Vec<Dir>,
|
pub directories: Vec<Dir>,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#[macro_use]
|
//#[macro_use]
|
||||||
extern crate failure_derive;
|
//extern crate failure_derive;
|
||||||
|
|
||||||
use clap::app_from_crate;
|
use clap::{app_from_crate, ArgMatches};
|
||||||
use clap::{Arg, App};
|
use clap::{Arg, App};
|
||||||
use libips::actions::{File, Manifest};
|
use libips::actions::{File, Manifest};
|
||||||
|
|
||||||
|
|
@ -13,40 +13,121 @@ mod errors {
|
||||||
}
|
}
|
||||||
|
|
||||||
use errors::Result;
|
use errors::Result;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fs::{read_dir};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let opts = app_from_crate!().arg(Arg::new("proto_dir")
|
let opts = app_from_crate!().subcommand(App::new("diff-component")
|
||||||
.short('p')
|
.about("shows differences between sample-manifest and manifests")
|
||||||
.long("proto-dir")
|
.arg(Arg::new("component")
|
||||||
.value_name("PROTO_DIR")
|
.takes_value(true)
|
||||||
.about("The Prototype directory where files are located after build")
|
.default_value("../sample_data/pkgs/cups")
|
||||||
.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();
|
).get_matches();
|
||||||
|
//.get_matches_from(vec!["pkg6dev", "diff-component"]);
|
||||||
|
|
||||||
let proto_dir = opts.value_of("proto_dir").expect("proto_dir is a mandatory variable. clap::Arg::required must be true");
|
if let Some(diff_component_opts) = opts.subcommand_matches("diff-component") {
|
||||||
|
let res = diff_component(diff_component_opts);
|
||||||
//let manifests: Vec<_> = opts.values_of("manifests").unwrap().collect();
|
if res.is_err() {
|
||||||
|
println!("error: {:?}", res.unwrap_err())
|
||||||
//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<Vec<File>> {
|
fn diff_component(matches: &ArgMatches) -> Result<()> {
|
||||||
let manifest = Manifest::parse_file(manifest_file)?;
|
let component_path = matches.value_of("component").unwrap();
|
||||||
let other_manifest = Manifest::parse_file(other_manifest_file)?;
|
|
||||||
|
|
||||||
println!("{:#?}", manifest);
|
let files = read_dir(component_path)?;
|
||||||
println!("{:#?}", other_manifest);
|
|
||||||
|
|
||||||
|
let manifest_files: Vec<String> = files
|
||||||
|
.filter_map(std::result::Result::ok)
|
||||||
|
.filter(|d| if let Some(e) = d.path().extension() { e == "p5m" } else {false})
|
||||||
|
.map(|e| e.path().into_os_string().into_string().unwrap()).collect();
|
||||||
|
|
||||||
Ok(vec![File::default()])
|
let sample_manifest_file = component_path.to_string() + "/manifests/sample-manifest.p5m";
|
||||||
|
|
||||||
|
let manifests_res: Result<Vec<Manifest>> = manifest_files.iter().map(|f|{
|
||||||
|
Manifest::parse_file(f.to_string())
|
||||||
|
}).collect();
|
||||||
|
let sample_manifest = Manifest::parse_file(sample_manifest_file)?;
|
||||||
|
|
||||||
|
let manifests: Vec<Manifest> = manifests_res.unwrap();
|
||||||
|
|
||||||
|
let missing_files = find_files_missing_in_manifests(&sample_manifest, manifests.clone())?;
|
||||||
|
|
||||||
|
for f in missing_files {
|
||||||
|
println!("file {} is missing in the manifests", f.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
let removed_files = find_removed_files(&sample_manifest, manifests.clone(), component_path)?;
|
||||||
|
|
||||||
|
for f in removed_files {
|
||||||
|
println!("file path={} has been removed from the sample-manifest", f.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show all files that have been removed in the sample-manifest
|
||||||
|
fn find_removed_files(sample_manifest: &Manifest, manifests: Vec<Manifest>, component_path: &str) -> Result<Vec<File>> {
|
||||||
|
let f_map = make_file_map(sample_manifest.files.clone());
|
||||||
|
let all_files: Vec<File> = manifests.iter().map(|m| m.files.clone()).flatten().collect();
|
||||||
|
|
||||||
|
let mut removed_files: Vec<File> = Vec::new();
|
||||||
|
|
||||||
|
for f in all_files {
|
||||||
|
match f.get_original_path() {
|
||||||
|
Some(path) => {
|
||||||
|
if !f_map.contains_key(path.as_str()) {
|
||||||
|
if !Path::new(&(component_path.to_string() + "/" + path.as_str())).exists() {
|
||||||
|
removed_files.push(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
if !f_map.contains_key(f.path.as_str()) {
|
||||||
|
removed_files.push(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(removed_files)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show all files missing in the manifests that are in sample_manifest
|
||||||
|
fn find_files_missing_in_manifests(sample_manifest: &Manifest, manifests: Vec<Manifest>) -> Result<Vec<File>> {
|
||||||
|
let all_files: Vec<File> = manifests.iter().map(|m| m.files.clone()).flatten().collect();
|
||||||
|
let f_map = make_file_map(all_files);
|
||||||
|
|
||||||
|
let mut missing_files: Vec<File> = Vec::new();
|
||||||
|
|
||||||
|
for f in sample_manifest.files.clone() {
|
||||||
|
match f.get_original_path() {
|
||||||
|
Some(path) => {
|
||||||
|
if !f_map.contains_key(path.as_str()) {
|
||||||
|
missing_files.push(f)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
if !f_map.contains_key(f.path.as_str()) {
|
||||||
|
missing_files.push(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(missing_files)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_file_map(files: Vec<File>) -> HashMap<String, File> {
|
||||||
|
files.iter().map(|f| {
|
||||||
|
let orig_path_opt = f.get_original_path();
|
||||||
|
if orig_path_opt == None {
|
||||||
|
return (f.path.clone(), f.clone());
|
||||||
|
}
|
||||||
|
(orig_path_opt.unwrap(), f.clone())
|
||||||
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue