(dockerfile: string, defaultLastStageName: string)
| 224 | |
| 225 | // not expected to be called externally (exposed for testing) |
| 226 | export function ensureDockerfileHasFinalStageName(dockerfile: string, defaultLastStageName: string): { lastStageName: string; modifiedDockerfile: string | undefined } { |
| 227 | |
| 228 | // Find the last line that starts with "FROM" (possibly preceeded by white-space) |
| 229 | const fromLines = [...dockerfile.matchAll(findFromLines)]; |
| 230 | if (fromLines.length === 0) { |
| 231 | throw new Error('Error parsing Dockerfile: Dockerfile contains no FROM instructions'); |
| 232 | } |
| 233 | |
| 234 | const lastFromLineMatch = fromLines[fromLines.length - 1]; |
| 235 | const lastFromLine = lastFromLineMatch.groups?.line as string; |
| 236 | |
| 237 | // Test for "FROM [--platform=someplat] base [as label]" |
| 238 | // That is, match against optional platform and label |
| 239 | const fromMatch = lastFromLine.match(parseFromLine); |
| 240 | if (!fromMatch) { |
| 241 | throw new Error('Error parsing Dockerfile: failed to parse final FROM line'); |
| 242 | } |
| 243 | if (fromMatch.groups?.label) { |
| 244 | return { |
| 245 | lastStageName: fromMatch.groups.label, |
| 246 | modifiedDockerfile: undefined, |
| 247 | }; |
| 248 | } |
| 249 | |
| 250 | // Last stage doesn't have a name, so modify the Dockerfile to set the name to defaultLastStageName |
| 251 | const lastLineStartIndex = (lastFromLineMatch.index as number) + (fromMatch.index as number); |
| 252 | const lastLineEndIndex = lastLineStartIndex + lastFromLine.length; |
| 253 | const matchedFromText = fromMatch[0]; |
| 254 | let modifiedDockerfile = dockerfile.slice(0, lastLineStartIndex + matchedFromText.length); |
| 255 | |
| 256 | modifiedDockerfile += ` AS ${defaultLastStageName}`; |
| 257 | const remainingFromLineLength = lastFromLine.length - matchedFromText.length; |
| 258 | modifiedDockerfile += dockerfile.slice(lastLineEndIndex - remainingFromLineLength); |
| 259 | |
| 260 | return { lastStageName: defaultLastStageName, modifiedDockerfile: modifiedDockerfile }; |
| 261 | } |
| 262 | |
| 263 | export function supportsBuildContexts(dockerfile: Dockerfile) { |
| 264 | const version = dockerfile.preamble.version; |
no outgoing calls
no test coverage detected