Add a little more smarts to the parser for finding required directives
This commit also adds some failing test cases
This commit is contained in:
parent
4eb6bfe406
commit
112e7f617a
|
@ -1,5 +1,25 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||
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 = "block-buffer"
|
||||
version = "0.7.3"
|
||||
|
@ -48,6 +68,19 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
|
@ -89,6 +122,24 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
||||
dependencies = [
|
||||
"quick-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jdp"
|
||||
version = "0.1.0"
|
||||
|
@ -98,8 +149,21 @@ dependencies = [
|
|||
"log",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"pretty_env_logger",
|
||||
]
|
||||
|
||||
[[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.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.11"
|
||||
|
@ -115,6 +179,12 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
|
@ -164,6 +234,16 @@ dependencies = [
|
|||
"sha-1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_env_logger"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
|
@ -173,6 +253,12 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
|
@ -182,6 +268,24 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.8.2"
|
||||
|
@ -205,6 +309,24 @@ 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 = "thread_local"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.12.0"
|
||||
|
@ -222,3 +344,34 @@ name = "unicode-xid"
|
|||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[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"
|
||||
|
|
|
@ -18,6 +18,7 @@ gumdrop = "~0.8.0"
|
|||
log = "~0.4.11"
|
||||
pest = "~2.1.3"
|
||||
pest_derive = "~2.1.0"
|
||||
pretty_env_logger = "~0.4.0"
|
||||
|
||||
[dev-dependencies]
|
||||
glob = "0.3"
|
||||
|
|
17
README.adoc
17
README.adoc
|
@ -21,3 +21,20 @@ This parser is **not** a Groovy syntax parser, and as such any advanced or wacky
|
|||
groovy that is littered around a `Jenkinsfile` should largely be ignored. This
|
||||
includes the `script` step which is basically checked to make sure that there is
|
||||
a `script { }` block, but anything within it is explicitly ignored.
|
||||
|
||||
|
||||
== Development
|
||||
|
||||
Development of `jdp` is all driven through the use of `cargo`, e.g. `cargo test`.
|
||||
|
||||
It's relatively straightforward to use a local test Jenkins environment to validate
|
||||
the `Jenkinsfile` located in `data/`. There is a major caveat in that many files
|
||||
will fail to validate if certain plugins are not installed on the Jenkins.
|
||||
|
||||
Once a local Jenkins is created, be sure to set a fixed sshd port in the
|
||||
`/configureSecurity` view (e.g. `2022`).
|
||||
|
||||
[source]
|
||||
----
|
||||
find data/valid -iname Jenkinsfile -exec ./scripts/declarative-linter {} \;
|
||||
----
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
pipeline {
|
||||
// Gotta have stages!
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
pipeline {
|
||||
agent any
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
echo ">> Linting $1 against a local Jenkins"
|
||||
ssh -p 2022 admin@localhost declarative-linter < $1
|
||||
echo "---"
|
38
src/lib.rs
38
src/lib.rs
|
@ -2,6 +2,7 @@ extern crate pest;
|
|||
#[macro_use]
|
||||
extern crate pest_derive;
|
||||
|
||||
use log::*;
|
||||
use pest::error::Error as PestError;
|
||||
use pest::Parser;
|
||||
use std::path::PathBuf;
|
||||
|
@ -23,7 +24,42 @@ pub fn parse_file(path: &PathBuf) -> Result<(), pest::error::Error<Rule>> {
|
|||
}
|
||||
|
||||
pub fn parse_pipeline_string(buffer: &str) -> Result<(), PestError<Rule>> {
|
||||
let _parser = PipelineParser::parse(Rule::pipeline, buffer)?;
|
||||
use pest::error::ErrorVariant;
|
||||
let mut parser = PipelineParser::parse(Rule::pipeline, buffer)?;
|
||||
|
||||
let mut agents = false;
|
||||
let mut stages = false;
|
||||
|
||||
while let Some(parsed) = parser.next() {
|
||||
match parsed.as_rule() {
|
||||
Rule::agentDecl => {
|
||||
if agents {
|
||||
warn!("Did I just see two agent directives?");
|
||||
}
|
||||
agents = true;
|
||||
},
|
||||
Rule::stagesDecl => {
|
||||
if stages {
|
||||
warn!("Did I just see two stages directives?");
|
||||
}
|
||||
stages = true;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Both agents and stages are required, the lack thereof is an error
|
||||
*/
|
||||
if !agents || !stages {
|
||||
let error = PestError::new_from_pos(
|
||||
ErrorVariant::ParsingError {
|
||||
positives: vec![],
|
||||
negatives: vec![],
|
||||
},
|
||||
pest::Position::from_start(buffer));
|
||||
return Err(error);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ struct CheckOpts {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
pretty_env_logger::init();
|
||||
let opts = JdpOptions::parse_args_default_or_exit();
|
||||
|
||||
if opts.command.is_none() {
|
||||
|
|
|
@ -8,16 +8,19 @@ pipeline = _{ SOI ~ shebang? ~
|
|||
opening_brace ~
|
||||
// I am pretty sure this grammar is wrong and there has to
|
||||
// a better way to allow these declarations anywhere within
|
||||
// the block, but still only allow one of each
|
||||
// the block, but still only allow one of each.
|
||||
// For now the parser code will have to inspect this itself
|
||||
(
|
||||
// An agent declaration at the root level is required
|
||||
agentDecl
|
||||
// A stages declaration is also required
|
||||
| stagesDecl
|
||||
| environmentDecl
|
||||
| optionsDecl
|
||||
| parametersDecl
|
||||
| postDecl
|
||||
| toolsDecl
|
||||
| triggersDecl
|
||||
| stagesDecl{1}
|
||||
)*
|
||||
~
|
||||
closing_brace ~
|
||||
|
|
Loading…
Reference in New Issue