Skip to content

Commit

Permalink
Merge pull request #11 from HewlettPackard/arg-spans
Browse files Browse the repository at this point in the history
Add spans to `ArgInstruction`
  • Loading branch information
timothyb89 authored Oct 19, 2020
2 parents 87f2970 + 3b53b53 commit 7306008
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 10 deletions.
19 changes: 19 additions & 0 deletions src/dockerfile_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,25 @@ impl Dockerfile {
pub fn splicer(&self) -> Splicer {
Splicer::from(self)
}

/// Attempts to find a global argument by name. Returns None if no global ARG
/// with the given name exists.
pub fn get_global_arg(&self, name: &str) -> Option<&ArgInstruction> {
for ins in &self.instructions {
match ins {
Instruction::Arg(a) => {
if a.name == name {
return Some(a);
} else {
continue
}
},
_ => return None
}
}

None
}
}

impl FromStr for Dockerfile {
Expand Down
41 changes: 31 additions & 10 deletions src/instructions/arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
use std::convert::TryFrom;

use crate::dockerfile_parser::Instruction;
use crate::parser::{Pair, Rule};
use crate::error::*;
use crate::parser::{Pair, Rule};
use crate::splicer::Span;

use enquote::unquote;
use snafu::ResultExt;
Expand All @@ -14,44 +15,64 @@ use snafu::ResultExt;
/// [arg]: https://docs.docker.com/engine/reference/builder/#arg
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ArgInstruction {
pub span: Span,

/// The argument key
pub name: String,

pub name_span: Span,

/// An optional argument value.
///
/// This may be unset when passing arguments through to later stages in a
/// [multi-stage build][build].
///
/// [build]: https://docs.docker.com/develop/develop-images/multistage-build/
pub value: Option<String>
pub value: Option<String>,

pub value_span: Option<Span>,
}

impl ArgInstruction {
pub(crate) fn from_record(record: Pair) -> Result<ArgInstruction> {
let span = Span::from_pair(&record);
let mut name = None;
let mut value = None;

for field in record.into_inner() {
match field.as_rule() {
Rule::arg_name => name = Some(field.as_str()),
Rule::arg_name => name = Some((field.as_str(), Span::from_pair(&field))),
Rule::arg_quoted_value => {
let v = unquote(field.as_str()).context(UnescapeError)?;

value = Some(v);
value = Some((v, Span::from_pair(&field)));
}
Rule::arg_value => value = Some(field.as_str().to_string()),
Rule::arg_value => value = Some((
field.as_str().to_string(),
Span::from_pair(&field)
)),
_ => return Err(unexpected_token(field))
}
}

let name = name.ok_or_else(|| Error::GenericParseError {
message: "arg name is required".into()
})?.to_string();
let (name, name_span) = match name {
Some((name, name_span)) => (name.to_string(), name_span),
_ => return Err(Error::GenericParseError {
message: "arg name is required".into()
})
};

let value = value.map(String::from);
let (value, value_span) = match value {
Some((value, value_span)) => (Some(value), Some(value_span)),
None => (None, None)
};

Ok(ArgInstruction {
name, value
span,
name,
name_span,
value,
value_span,
})
}
}
Expand Down

0 comments on commit 7306008

Please sign in to comment.