fun createZipWithModuleFiles()

in plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerSessionContext.kt [205:308]


    fun createZipWithModuleFiles(copyResult: MavenCopyCommandsResult?): ZipCreationResult {
        val root = configurationFile?.parent
        val sourceFolder = File(root?.path)
        val buildLogBuilder = StringBuilder("Starting Build Log...\n")
        val depDirectory = if (copyResult is MavenCopyCommandsResult.Success) {
            showTransformationHub()
            copyResult.dependencyDirectory
        } else if (copyResult != null) { // failure cases already handled by now, but to be safe set depDir to null if copyResult failed
            null
        } else {
            sqlMetadataZip // null copyResult means doing a SQL conversion
        }

        return runReadAction {
            try {
                val dirsToExclude = findDirectoriesToExclude(sourceFolder)
                val files = root?.let {
                    VfsUtil.collectChildrenRecursively(it).filter { child ->
                        val childPath = Path(child.path)
                        !child.isDirectory && !child.name.endsWith(DS_STORE_FILE_NAME) && dirsToExclude.none { dir -> childPath.startsWith(dir.toPath()) }
                    }
                }
                val dependencyFiles = if (depDirectory != null) {
                    iterateThroughDependencies(depDirectory)
                } else {
                    mutableListOf()
                }

                val zipSources = File(ZIP_SOURCES_PATH)
                val depSources = File(ZIP_DEPENDENCIES_PATH)
                val outputFile = createTemporaryZipFile { zip ->
                    // 1) Manifest file
                    var manifest = ZipManifest(transformCapabilities = transformCapabilities, customBuildCommand = customBuildCommand)
                    if (sqlMetadataZip != null) {
                        // doing a SQL conversion, not language upgrade
                        val sctFileName = sqlMetadataZip.listFiles { file -> file.name.endsWith(".sct") }.first().name
                        manifest = ZipManifest(
                            requestedConversions = RequestedConversions(
                                SQLConversion(sourceVendor, targetVendor, schema, sourceServerName, sctFileName)
                            )
                        )
                    }
                    mapper.writeValueAsString(manifest)
                        .byteInputStream()
                        .use {
                            zip.putNextEntry(Path(MANIFEST_PATH).toString(), it)
                        }

                    // 2) Dependencies / SQL conversion metadata
                    if (depDirectory != null) {
                        dependencyFiles.forEach { depFile ->
                            val relativePath = File(depFile.path).relativeTo(depDirectory)
                            val paddedPath = depSources.resolve(relativePath)
                            var paddedPathString = paddedPath.toPath().toString()
                            // Convert Windows file path to work on Linux
                            if (File.separatorChar != '/') {
                                paddedPathString = paddedPathString.replace('\\', '/')
                            }
                            depFile.inputStream().use {
                                zip.putNextEntry(paddedPathString, it)
                            }
                        }
                    }

                    LOG.info { "Dependency files size = ${dependencyFiles.sumOf { it.length().toInt() }}" }

                    // 3) Sources
                    files?.forEach { file ->
                        val relativePath = File(file.path).relativeTo(sourceFolder)
                        val paddedPath = zipSources.resolve(relativePath)
                        var paddedPathString = paddedPath.toPath().toString()
                        // Convert Windows file path to work on Linux
                        if (File.separatorChar != '/') {
                            paddedPathString = paddedPathString.replace('\\', '/')
                        }
                        try {
                            file.inputStream.use {
                                zip.putNextEntry(paddedPathString, it)
                            }
                        } catch (e: NoSuchFileException) {
                            // continue without failing
                            LOG.error { "NoSuchFileException likely due to a symlink, skipping file" }
                        }
                    }

                    LOG.info { "Source code files size = ${files?.sumOf { it.length.toInt() }}" }

                    // 4) Build Log
                    buildLogBuilder.toString().byteInputStream().use {
                        zip.putNextEntry(Path(BUILD_LOG_PATH).toString(), it)
                    }
                }.toFile()
                // depDirectory should never be null
                if (depDirectory != null) ZipCreationResult.Succeeded(outputFile) else ZipCreationResult.Missing1P(outputFile)
            } catch (e: NoSuchFileException) {
                throw CodeModernizerException("Source folder not found")
            } catch (e: Exception) {
                LOG.error(e) { e.message.toString() }
                throw CodeModernizerException("Unknown exception occurred")
            } finally {
                depDirectory?.deleteRecursively()
            }
        }
    }