fun parse()

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)
    }