All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.triplet.gradle.play.tasks.GenerateEdit.kt Maven / Gradle / Ivy

package com.github.triplet.gradle.play.tasks

import com.github.triplet.gradle.androidpublisher.EditResponse
import com.github.triplet.gradle.androidpublisher.PlayPublisher
import com.github.triplet.gradle.common.utils.marked
import com.github.triplet.gradle.common.utils.nullOrFull
import com.github.triplet.gradle.common.utils.orNull
import com.github.triplet.gradle.common.utils.safeCreateNewFile
import com.github.triplet.gradle.play.PlayPublisherExtension
import com.github.triplet.gradle.play.internal.PlayExtensionConfig
import com.github.triplet.gradle.play.internal.serializableConfig
import com.github.triplet.gradle.play.internal.serviceAccountCredentialsOrDefault
import com.github.triplet.gradle.play.tasks.internal.EditTaskBase
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.logging.Logging
import org.gradle.api.provider.Property
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.submit
import org.gradle.kotlin.dsl.support.serviceOf
import org.gradle.workers.WorkAction
import org.gradle.workers.WorkParameters
import org.gradle.workers.WorkerExecutor
import javax.inject.Inject

internal abstract class GenerateEdit @Inject constructor(
        extension: PlayPublisherExtension
) : EditTaskBase(extension) {
    init {
        // Always out-of-date since we need a new edit for every build. At some point, it would be
        // nice to run this only if dependent tasks are actually running (aka not up-to-date).
        outputs.upToDateWhen { false }
    }

    @TaskAction
    fun generate() {
        val editId = editIdFile
        project.serviceOf().noIsolation().submit(Generator::class) {
            config.set(extension.serializableConfig)
            editIdFile.set(editId)
        }
    }

    abstract class Generator @Inject constructor(
            private val fileOps: FileSystemOperations
    ) : WorkAction {
        private val file = parameters.editIdFile.get().asFile
        private val appId = file.nameWithoutExtension
        private val publisher = PlayPublisher(
                parameters.config.get().serviceAccountCredentialsOrDefault,
                parameters.config.get().serviceAccountEmail,
                appId
        )

        override fun execute() {
            file.safeCreateNewFile().writeText(getOrCreateEditId())
        }

        private fun getOrCreateEditId(): String {
            val editId = file.orNull()?.readText().nullOrFull()?.takeIf {
                file.marked("skipped").exists()
            }
            fileOps.delete { delete(file.editIdAndFriends) }

            val response = if (editId == null) {
                publisher.insertEdit()
            } else {
                file.marked("skipped").safeCreateNewFile()
                publisher.getEdit(editId)
            }

            return when (response) {
                is EditResponse.Success -> response.id
                is EditResponse.Failure -> handleFailure(response)
            }
        }

        private fun handleFailure(response: EditResponse.Failure): String {
            if (response.isNewApp()) {
                // Rethrow for clarity
                response.rethrow("""
                    |No application found for the package name '$appId'. The first version of your
                    |app must be uploaded via the Play Console.
                """.trimMargin())
            } else if (response.isInvalidEdit()) {
                Logging.getLogger(GenerateEdit::class.java)
                        .error("Failed to retrieve saved edit, regenerating.")
                return getOrCreateEditId()
            } else if (response.isUnauthorized()) {
                response.rethrow("""
                    |Service account not authenticated. See the README for instructions:
                    |https://github.com/Triple-T/gradle-play-publisher#service-account
                """.trimMargin())
            } else {
                response.rethrow()
            }
        }

        interface Params : WorkParameters {
            val config: Property
            val editIdFile: RegularFileProperty
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy