in jetbrains-core/src/software/aws/toolkits/jetbrains/core/docker/DockerfileParser.kt [20:55]
fun parse(virtualFile: VirtualFile): DockerfileDetails? {
val psiFile = PsiManager.getInstance(project).findFile(virtualFile)!!
val contextDirectory = virtualFile.parent.path
val lastFromCommand = psiFile.children.filterIsInstance<DockerFileFromCommand>().lastOrNull() ?: return null
val commandsAfterLastFrom = psiFile.children.dropWhile { it != lastFromCommand }
if (commandsAfterLastFrom.isEmpty()) {
return null
}
val command = commandsAfterLastFrom.filterIsInstance<DockerFileCmdCommand>().lastOrNull()?.text?.substringAfter("CMD ")
val portMappings = commandsAfterLastFrom.filterIsInstance<DockerFileExposeCommand>().mapNotNull {
it.listChildren().find { child -> (child as? LeafPsiElement)?.elementType?.toString() == "INTEGER_LITERAL" }?.text?.toIntOrNull()
}
val copyDirectives = groupByWorkDir(commandsAfterLastFrom).flatMap { (workDir, commands) ->
commands.filterIsInstance<DockerFileAddOrCopyCommand>()
.filter { it.copyKeyword != null }
.mapNotNull { cmd -> cmd.fileOrUrlList.takeIf { it.size == 2 }?.let { it.first().text to it.last().text } }
.map { (rawLocal, rawRemote) ->
val local = if (rawLocal.startsWith("/") || rawLocal.startsWith(File.separatorChar)) {
rawLocal
} else {
"${contextDirectory.normalizeDirectory(true)}$rawLocal"
}
val remote = if (rawRemote.startsWith("/") || workDir == null) {
rawRemote
} else {
"${workDir.normalizeDirectory()}$rawRemote"
}
CopyDirective(local, remote)
}
}
return DockerfileDetails(command, portMappings, copyDirectives)
}