dockerfile_parser/instructions/
entrypoint.rs1use std::convert::TryFrom;
4
5use crate::Span;
6use crate::dockerfile_parser::Instruction;
7use crate::error::*;
8use crate::util::*;
9use crate::parser::*;
10
11#[derive(Debug, PartialEq, Eq, Clone)]
18pub struct EntrypointInstruction {
19 pub span: Span,
20 pub expr: ShellOrExecExpr,
21}
22
23impl EntrypointInstruction {
24 pub(crate) fn from_record(record: Pair) -> Result<EntrypointInstruction> {
25 let span = Span::from_pair(&record);
26 let field = record.into_inner().next().unwrap();
27
28 match field.as_rule() {
29 Rule::entrypoint_exec => Ok(EntrypointInstruction {
30 span,
31 expr: ShellOrExecExpr::Exec(parse_string_array(field)?),
32 }),
33 Rule::entrypoint_shell => Ok(EntrypointInstruction {
34 span,
35 expr: ShellOrExecExpr::Shell(parse_any_breakable(field)?),
36 }),
37 _ => Err(unexpected_token(field)),
38 }
39 }
40
41 pub fn into_shell(self) -> Option<BreakableString> {
44 self.expr.into_shell()
45 }
46
47 pub fn as_shell(&self) -> Option<&BreakableString> {
50 self.expr.as_shell()
51 }
52
53 pub fn into_exec(self) -> Option<StringArray> {
56 self.expr.into_exec()
57 }
58
59 pub fn as_exec(&self) -> Option<&StringArray> {
62 self.expr.as_exec()
63 }
64}
65
66impl TryFrom<Instruction> for EntrypointInstruction {
67 type Error = Error;
68
69 fn try_from(instruction: Instruction) -> std::result::Result<Self, Self::Error> {
70 if let Instruction::Entrypoint(e) = instruction {
71 Ok(e)
72 } else {
73 Err(Error::ConversionError {
74 from: format!("{:?}", instruction),
75 to: "EntrypointInstruction".into()
76 })
77 }
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use indoc::indoc;
84 use pretty_assertions::assert_eq;
85
86 use super::*;
87 use crate::Span;
88 use crate::test_util::*;
89
90 #[test]
91 fn entrypoint_basic() -> Result<()> {
92 assert_eq!(
93 parse_single(r#"entrypoint echo "hello world""#, Rule::entrypoint)?
94 .as_entrypoint().unwrap()
95 .as_shell().unwrap(),
96 &BreakableString::new((11, 29))
97 .add_string((11, 29), "echo \"hello world\"")
98 );
99
100 assert_eq!(
101 parse_single(r#"entrypoint ["echo", "hello world"]"#, Rule::entrypoint)?,
102 EntrypointInstruction {
103 span: Span::new(0, 34),
104 expr: ShellOrExecExpr::Exec(StringArray {
105 span: Span::new(11, 34),
106 elements: vec![SpannedString {
107 span: Span::new(12, 18),
108 content: "echo".to_string(),
109 }, SpannedString {
110 span: Span::new(20, 33),
111 content: "hello world".to_string(),
112 }]
113 })
114 }.into()
115 );
116
117 Ok(())
118 }
119
120 #[test]
121 fn entrypoint_multiline_exec() -> Result<()> {
122 assert_eq!(
123 parse_single(r#"entrypoint\
124 [\
125 "echo", \
126 "hello world"\
127 ]"#, Rule::entrypoint)?,
128 EntrypointInstruction {
129 span: Span::new(0, 73),
130 expr: ShellOrExecExpr::Exec(StringArray {
131 span: Span::new(20, 73),
132 elements: vec![SpannedString {
133 span: Span::new(31, 37),
134 content: "echo".to_string(),
135 }, SpannedString {
136 span: Span::new(49, 62),
137 content: "hello world".to_string(),
138 }]
139 }),
140 }.into()
141 );
142
143 Ok(())
144 }
145
146 #[test]
147 fn entrypoint_multiline_shell() -> Result<()> {
148 assert_eq!(
149 parse_single(indoc!(r#"
150 entrypoint echo \
151 "hello world"
152 "#), Rule::entrypoint)?
153 .as_entrypoint().unwrap()
154 .as_shell().unwrap(),
155 &BreakableString::new((11, 33))
156 .add_string((11, 16), "echo ")
157 .add_string((18, 33), " \"hello world\"")
158 );
159
160 Ok(())
161 }
162
163 #[test]
164 fn entrypoint_multiline_large() -> Result<()> {
165 let ins = parse_single(
168 indoc!(r#"
169 entrypoint set -x && \
170 # lorem ipsum
171 echo "hello world" && \
172 # dolor sit amet,
173 # consectetur \
174 # adipiscing elit, \
175 # sed do eiusmod
176 # tempor incididunt ut labore
177 echo foo && \
178 echo 'bar' \
179 && echo baz \
180 # et dolore magna aliqua."#),
181 Rule::entrypoint
182 )?.into_entrypoint().unwrap().into_shell().unwrap();
183
184 assert_eq!(
185 ins,
186 BreakableString::new((11, 273))
187 .add_string((11, 21), "set -x && ")
188 .add_comment((27, 40), "# lorem ipsum")
189 .add_string((41, 67), " echo \"hello world\" && ")
190 .add_comment((73, 90), "# dolor sit amet,")
191 .add_comment((95, 110), "# consectetur \\")
192 .add_comment((115, 135), "# adipiscing elit, \\")
193 .add_comment((140, 156), "# sed do eiusmod")
194 .add_comment((161, 190), "# tempor incididunt ut labore")
195 .add_string((191, 207), " echo foo && ")
196 .add_string((209, 224), " echo 'bar' ")
197 .add_string((226, 242), " && echo baz ")
198 .add_comment((248, 273), "# et dolore magna aliqua.")
199 );
200
201 assert_eq!(
202 ins.to_string(),
203 r#"set -x && echo "hello world" && echo foo && echo 'bar' && echo baz "#
204 );
205
206 Ok(())
207 }
208}