1#[derive(PartialEq, Eq, Clone, Copy, Debug, Ord, PartialOrd)]
8pub struct Span {
9 pub start: usize,
10 pub end: usize,
11}
12
13impl Span {
14 pub fn new(start: usize, end: usize) -> Span {
15 Span { start, end }
16 }
17
18 pub fn relative_span(&self, dockerfile: &Dockerfile) -> (usize, Span) {
20 let mut line_start_offset = 0;
21 let mut lines = 0;
22 for (i, c) in dockerfile.content.as_bytes().iter().enumerate() {
23 if i == self.start {
24 break;
25 }
26 if *c == b'\n' {
27 lines += 1;
28 line_start_offset = i + 1;
29 }
30 }
31
32 let start = self.start - line_start_offset;
33 let end = start + (self.end - self.start);
34 (lines, Span { start, end })
35 }
36}
37
38impl From<(usize, usize)> for Span {
39 fn from(tup: (usize, usize)) -> Span {
40 Span::new(tup.0, tup.1)
41 }
42}
43
44#[derive(Debug, Clone, PartialEq)]
46pub struct Dockerfile {
47 pub content: String,
49 pub instructions: Vec<Instruction>,
51 pub escape: char,
54}
55
56impl Dockerfile {
57 pub fn parse(input: &str) -> Result<Dockerfile, monch::ParseErrorFailureError> {
59 crate::parser::parse(input)
60 }
61}
62
63#[derive(Debug, PartialEq, Eq, Clone)]
65pub enum Instruction {
66 From(FromInstruction),
67 Arg(ArgInstruction),
68 Label(LabelInstruction),
69 Run(RunInstruction),
70 Entrypoint(EntrypointInstruction),
71 Cmd(CmdInstruction),
72 Copy(CopyInstruction),
73 Env(EnvInstruction),
74 Shell(ShellInstruction),
75 Onbuild(OnbuildInstruction),
76 Healthcheck(HealthcheckInstruction),
77 Heredoc(HeredocInstruction),
78 Misc(MiscInstruction),
79 Unknown(SpannedString),
82}
83
84impl Instruction {
85 pub fn span(&self) -> Span {
86 match self {
87 Instruction::From(i) => i.span,
88 Instruction::Arg(i) => i.span,
89 Instruction::Label(i) => i.span,
90 Instruction::Run(i) => i.span,
91 Instruction::Entrypoint(i) => i.span,
92 Instruction::Cmd(i) => i.span,
93 Instruction::Copy(i) => i.span,
94 Instruction::Env(i) => i.span,
95 Instruction::Shell(i) => i.span,
96 Instruction::Onbuild(i) => i.span,
97 Instruction::Healthcheck(i) => i.span,
98 Instruction::Heredoc(i) => i.span,
99 Instruction::Misc(i) => i.span,
100 Instruction::Unknown(i) => i.span,
101 }
102 }
103}
104
105#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
107pub struct SpannedString {
108 pub span: Span,
109 pub content: String,
110}
111
112#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
114pub struct SpannedComment {
115 pub span: Span,
116 pub content: String,
117}
118
119#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
121pub struct StringArray {
122 pub span: Span,
123 pub elements: Vec<SpannedString>,
124}
125
126#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
128pub enum BreakableStringComponent {
129 String(SpannedString),
130 Comment(SpannedComment),
131}
132
133#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
136pub struct BreakableString {
137 pub span: Span,
138 pub components: Vec<BreakableStringComponent>,
139}
140
141#[derive(Debug, PartialEq, Eq, Clone)]
143pub enum ShellOrExecExpr {
144 Shell(BreakableString),
145 Exec(StringArray),
146}
147
148#[derive(Debug, PartialEq, Eq, Clone)]
150pub struct FromInstruction {
151 pub span: Span,
152 pub flags: Vec<FromFlag>,
153 pub image: SpannedString,
154 pub alias: Option<SpannedString>,
155}
156
157#[derive(Debug, PartialEq, Eq, Clone)]
159pub struct FromFlag {
160 pub span: Span,
161 pub name: SpannedString,
162 pub value: SpannedString,
163}
164
165#[derive(Debug, Clone, PartialEq, Eq)]
167pub struct ArgInstruction {
168 pub span: Span,
169 pub name: SpannedString,
170 pub value: Option<SpannedString>,
171}
172
173#[derive(Debug, PartialEq, Eq, Clone)]
175pub struct LabelInstruction {
176 pub span: Span,
177 pub labels: Vec<Label>,
178}
179
180#[derive(Debug, PartialEq, Eq, Clone)]
182pub struct Label {
183 pub span: Span,
184 pub name: SpannedString,
185 pub value: SpannedString,
186}
187
188#[derive(Debug, PartialEq, Eq, Clone)]
190pub struct RunInstruction {
191 pub span: Span,
192 pub expr: ShellOrExecExpr,
193}
194
195#[derive(Debug, PartialEq, Eq, Clone)]
197pub struct EntrypointInstruction {
198 pub span: Span,
199 pub expr: ShellOrExecExpr,
200}
201
202#[derive(Debug, PartialEq, Eq, Clone)]
204pub struct CmdInstruction {
205 pub span: Span,
206 pub expr: ShellOrExecExpr,
207}
208
209#[derive(Debug, PartialEq, Eq, Clone)]
211pub struct CopyInstruction {
212 pub span: Span,
213 pub flags: Vec<CopyFlag>,
214 pub args: CopyArgs,
215}
216
217#[derive(Debug, PartialEq, Eq, Clone)]
220pub enum CopyArgs {
221 Paths { sources: Vec<SpannedString>, destination: SpannedString },
222 Exec(StringArray),
223}
224
225#[derive(Debug, PartialEq, Eq, Clone)]
227pub struct CopyFlag {
228 pub span: Span,
229 pub name: SpannedString,
230 pub value: SpannedString,
231}
232
233#[derive(Debug, PartialEq, Eq, Clone)]
235pub struct EnvInstruction {
236 pub span: Span,
237 pub vars: Vec<EnvVar>,
238}
239
240#[derive(Debug, PartialEq, Eq, Clone)]
242pub struct EnvVar {
243 pub span: Span,
244 pub key: SpannedString,
245 pub value: BreakableString,
246}
247
248#[derive(Debug, PartialEq, Eq, Clone)]
251pub struct ShellInstruction {
252 pub span: Span,
253 pub expr: ShellOrExecExpr,
254}
255
256#[derive(Debug, PartialEq, Eq, Clone)]
258pub struct OnbuildInstruction {
259 pub span: Span,
260 pub instruction: Box<Instruction>,
261}
262
263#[derive(Debug, PartialEq, Eq, Clone)]
268pub struct HealthcheckInstruction {
269 pub span: Span,
270 pub flags: Vec<HealthcheckFlag>,
271 pub cmd: Option<Box<Instruction>>,
272}
273
274#[derive(Debug, PartialEq, Eq, Clone)]
277pub struct HealthcheckFlag {
278 pub span: Span,
279 pub name: SpannedString,
280 pub value: SpannedString,
281}
282
283#[derive(Debug, PartialEq, Eq, Clone)]
297pub struct HeredocInstruction {
298 pub span: Span,
299 pub instruction: Box<Instruction>,
300 pub body: String,
301}
302
303#[derive(Debug, PartialEq, Eq, Clone)]
308pub struct MiscInstruction {
309 pub span: Span,
310 pub instruction: SpannedString,
311 pub arguments: BreakableString,
312}