#[derive(PartialEq, Eq, Clone, Copy, Debug, Ord, PartialOrd)]
pub struct Span {
pub start: usize,
pub end: usize,
}
impl Span {
pub fn new(start: usize, end: usize) -> Span {
Span { start, end }
}
pub fn relative_span(&self, dockerfile: &Dockerfile) -> (usize, Span) {
let mut line_start_offset = 0;
let mut lines = 0;
for (i, c) in dockerfile.content.as_bytes().iter().enumerate() {
if i == self.start {
break;
}
if *c == b'\n' {
lines += 1;
line_start_offset = i + 1;
}
}
let start = self.start - line_start_offset;
let end = start + (self.end - self.start);
(lines, Span { start, end })
}
}
impl From<(usize, usize)> for Span {
fn from(tup: (usize, usize)) -> Span {
Span::new(tup.0, tup.1)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Dockerfile {
pub content: String,
pub instructions: Vec<Instruction>,
pub escape: char,
}
impl Dockerfile {
pub fn parse(input: &str) -> Result<Dockerfile, monch::ParseErrorFailureError> {
crate::parser::parse(input)
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Instruction {
From(FromInstruction),
Arg(ArgInstruction),
Label(LabelInstruction),
Run(RunInstruction),
Entrypoint(EntrypointInstruction),
Cmd(CmdInstruction),
Copy(CopyInstruction),
Env(EnvInstruction),
Shell(ShellInstruction),
Onbuild(OnbuildInstruction),
Healthcheck(HealthcheckInstruction),
Heredoc(HeredocInstruction),
Misc(MiscInstruction),
Unknown(SpannedString),
}
impl Instruction {
pub fn span(&self) -> Span {
match self {
Instruction::From(i) => i.span,
Instruction::Arg(i) => i.span,
Instruction::Label(i) => i.span,
Instruction::Run(i) => i.span,
Instruction::Entrypoint(i) => i.span,
Instruction::Cmd(i) => i.span,
Instruction::Copy(i) => i.span,
Instruction::Env(i) => i.span,
Instruction::Shell(i) => i.span,
Instruction::Onbuild(i) => i.span,
Instruction::Healthcheck(i) => i.span,
Instruction::Heredoc(i) => i.span,
Instruction::Misc(i) => i.span,
Instruction::Unknown(i) => i.span,
}
}
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
pub struct SpannedString {
pub span: Span,
pub content: String,
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
pub struct SpannedComment {
pub span: Span,
pub content: String,
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
pub struct StringArray {
pub span: Span,
pub elements: Vec<SpannedString>,
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
pub enum BreakableStringComponent {
String(SpannedString),
Comment(SpannedComment),
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
pub struct BreakableString {
pub span: Span,
pub components: Vec<BreakableStringComponent>,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum ShellOrExecExpr {
Shell(BreakableString),
Exec(StringArray),
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct FromInstruction {
pub span: Span,
pub flags: Vec<FromFlag>,
pub image: SpannedString,
pub alias: Option<SpannedString>,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct FromFlag {
pub span: Span,
pub name: SpannedString,
pub value: SpannedString,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ArgInstruction {
pub span: Span,
pub name: SpannedString,
pub value: Option<SpannedString>,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct LabelInstruction {
pub span: Span,
pub labels: Vec<Label>,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Label {
pub span: Span,
pub name: SpannedString,
pub value: SpannedString,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct RunInstruction {
pub span: Span,
pub expr: ShellOrExecExpr,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct EntrypointInstruction {
pub span: Span,
pub expr: ShellOrExecExpr,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct CmdInstruction {
pub span: Span,
pub expr: ShellOrExecExpr,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct CopyInstruction {
pub span: Span,
pub flags: Vec<CopyFlag>,
pub args: CopyArgs,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum CopyArgs {
Paths { sources: Vec<SpannedString>, destination: SpannedString },
Exec(StringArray),
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct CopyFlag {
pub span: Span,
pub name: SpannedString,
pub value: SpannedString,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct EnvInstruction {
pub span: Span,
pub vars: Vec<EnvVar>,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct EnvVar {
pub span: Span,
pub key: SpannedString,
pub value: BreakableString,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ShellInstruction {
pub span: Span,
pub expr: ShellOrExecExpr,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct OnbuildInstruction {
pub span: Span,
pub instruction: Box<Instruction>,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct HealthcheckInstruction {
pub span: Span,
pub flags: Vec<HealthcheckFlag>,
pub cmd: Option<Box<Instruction>>,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct HealthcheckFlag {
pub span: Span,
pub name: SpannedString,
pub value: SpannedString,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct HeredocInstruction {
pub span: Span,
pub instruction: Box<Instruction>,
pub body: String,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct MiscInstruction {
pub span: Span,
pub instruction: SpannedString,
pub arguments: BreakableString,
}