Implement a simple processor for travis-ci.yml files

Currently this emits data only to standard out, but it will likely need to learn
how to drop this payload directly onto the eventbus in the near future
This commit is contained in:
R Tyler Croy 2020-01-13 08:47:00 -08:00
parent c93be57709
commit cba11b7e82
No known key found for this signature in database
GPG Key ID: E5C92681BEF6CEA2
4 changed files with 206 additions and 6 deletions

37
Cargo.lock generated
View File

@ -1487,6 +1487,17 @@ dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "processor-travis-ci"
version = "0.1.0"
dependencies = [
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quick-error"
version = "1.2.2"
@ -1818,6 +1829,17 @@ dependencies = [
"url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_yaml"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sha-1"
version = "0.8.1"
@ -1999,10 +2021,6 @@ dependencies = [
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "travis-ci"
version = "0.1.0"
[[package]]
name = "trust-dns-proto"
version = "0.18.0-alpha.2"
@ -2120,6 +2138,15 @@ name = "utf8parse"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "uuid"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "vcpkg"
version = "0.2.8"
@ -2438,6 +2465,7 @@ dependencies = [
"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7"
"checksum serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5"
"checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
"checksum shellexpand 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a23aed0018ea07316c7826ade41e551772031cf652805f93ebc922215a44d4a"
@ -2471,6 +2499,7 @@ dependencies = [
"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61"
"checksum utf-8 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
"checksum utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d"
"checksum uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
"checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"

1
processors/travis-ci/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
target/

View File

@ -1,5 +1,5 @@
[package]
name = "travis-ci"
name = "processor-travis-ci"
version = "0.1.0"
authors = ["R. Tyler Croy <rtyler@brokenco.de>"]
edition = "2018"
@ -7,3 +7,12 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = "~1.0.103"
serde_json = "~1.0.0"
serde_yaml = "~0.8.11"
# Handling command line options
clap = { version = "~2.33.0", features = ["yaml"] }
# Needed for generating uuids
uuid = { version = "~0.8.1", features = ["serde", "v4"] }

View File

@ -1,3 +1,164 @@
extern crate clap;
extern crate serde;
extern crate serde_yaml;
extern crate uuid;
use clap::{Arg, App};
use serde::{Deserialize, Serialize};
use serde_yaml::Value;
use uuid::Uuid;
use std::collections::HashMap;
use std::fs;
fn main() {
println!("Hello, world!");
let matches = App::new("travis processor")
.arg(Arg::with_name("filename")
.short("f")
.long("filename")
.value_name("FILE")
.required(true)
.help("File")
.takes_value(true))
.get_matches();
let filename = matches.value_of("filename").unwrap_or(".travis-ci.yml");
let contents = fs::read_to_string(filename).expect("Something went wrong reading the file");
let pipeline = serde_yaml::from_str::<TravisConfig>(&contents)
.expect("Failed to deserialize the yaml file into a TravisConfig");
let mut output = PipelineManifest {
tasks: vec![],
};
let mut caps = HashMap::new();
if pipeline.sudo {
caps.insert("docker_run".to_string(), Value::Bool(false));
}
else {
caps.insert("docker_run".to_string(), Value::Bool(true));
}
let mut task = Task {
id: Uuid::new_v4().to_string(),
capabilities: caps,
ops: vec![],
};
task.ops.push(Op {
id: Uuid::new_v4().to_string(),
op_type: OpType::BeginContext,
// Cheap quick hack to get a simple hashmap here
data: serde_yaml::from_str(r#"{ name: "Travis" }"#).unwrap(),
});
for script in pipeline.script.iter() {
let mut data = HashMap::new();
data.insert("script".to_string(), Value::String(script.to_string()));
data.insert("timeout_s".to_string(), Value::Number(serde_yaml::Number::from(300)));
data.insert("env".to_string(), Value::Null);
task.ops.push(Op {
id: Uuid::new_v4().to_string(),
op_type: OpType::RunProcess,
data
});
}
task.ops.push(Op {
id: Uuid::new_v4().to_string(),
op_type: OpType::EndContext,
// Cheap quick hack to get a simple hashmap here
data: serde_yaml::from_str(r#"{ name: "Travis" }"#).unwrap(),
});
output.tasks.push(task);
println!("{}", serde_yaml::to_string(&output).expect("Failed to serialize manifest"));
}
#[derive(Deserialize, Debug, Serialize)]
struct TravisConfig {
sudo: bool,
script: Vec<String>,
}
#[derive(Deserialize, Debug, PartialEq, Serialize)]
enum OpType {
#[serde(rename = "BEGINCTX")]
BeginContext,
#[serde(rename = "RUNPROC")]
RunProcess,
#[serde(rename = "ENDCTX")]
EndContext,
}
#[derive(Deserialize, Debug, Serialize)]
struct Op {
id: String,
#[serde(rename = "type")]
op_type: OpType,
data: HashMap<String, Value>,
}
#[derive(Deserialize, Debug, Serialize)]
struct Task {
id: String,
capabilities: HashMap<String, Value>,
ops: Vec<Op>,
}
#[derive(Deserialize, Debug, Serialize)]
struct PipelineManifest {
// meta: Meta,
tasks: Vec<Task>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deser_simple() {
let yaml = r#"
---
sudo: false
script:
- echo "Hello World"
- env
"#;
let c = serde_yaml::from_str::<TravisConfig>(yaml).unwrap();
assert!(!c.sudo);
assert_eq!(c.script.len(), 2);
}
#[test]
fn deser_yaml() {
let yaml = r#"
---
meta:
tasks:
- id: 0x1
capabilities:
docker_run: true
ops:
- id: 1
type: BEGINCTX
data:
name: 'Travis'
- id: 2
type: RUNPROC
data:
script: 'echo "Hello World"'
env:
timeout_s: 300
- id: 3
type: ENDCTX
data:
name: 'Travis'
"#;
let c = serde_yaml::from_str::<PipelineManifest>(yaml).unwrap();
assert_eq!(c.tasks.len(), 1);
assert_eq!(c.tasks[0].ops.len(), 3);
assert_eq!(c.tasks[0].ops[0].op_type, OpType::BeginContext);
}
}