<commit_before>package org.gradle.kotlin.dsl.integration

import org.gradle.integtests.fixtures.ToBeFixedForConfigurationCache
import org.gradle.kotlin.dsl.fixtures.AbstractKotlinIntegrationTest
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test


class BuildScriptCompileAvoidanceIntegrationTest : AbstractKotlinIntegrationTest() {

    @Before
    fun init() {
        withSettings(
            """
            rootProject.name = "test-project"
            """
        )
    }

    @Test
    fun `does not recompile buildscript on non ABI change in buildSrc`() {
        val className = givenClassInBuildSrcContains(
            """
            public void t1() {
                System.out.println("foo");
            }
            """
        )
        withBuildScript("$className().t1()")
        configureProject().buildScriptCompiled().andOutputContains("foo")

        givenClassInBuildSrcContains(
            """
            public void t1() {
                System.out.println("bar");
            }
            """
        )
        configureProject().buildScriptNotCompiled().andOutputContains("bar")
    }

    @Test
    fun `recompiles buildscript on ABI change in buildSrc`() {
        val className = givenClassInBuildSrcContains(
            """
            public void t2() {
                System.out.println("foo");
            }
            """
        )
        withBuildScript("$className().t2()")
        configureProject().buildScriptCompiled().andOutputContains("foo")

        givenClassInBuildSrcContains(
            """
            public void t2() {
                System.out.println("bar");
            }
            public void bar() {}
            """
        )
        configureProject().buildScriptCompiled().andOutputContains("bar")
    }

    @ToBeFixedForConfigurationCache
    @Test
    fun `does not recompile buildscript on non ABI change in buildscript classpath`() {
        val (className, jarPath) = buildJarForBuildScriptClasspath(
            """
            public void t3() {
                System.out.println("foo");
            }
            """
        )

        withBuildScript(
            """
            buildscript {
                dependencies { classpath(files("$jarPath")) }
            }
            $className().t3()
            """
        )
        configureProject().buildScriptCompiled().andOutputContains("foo")

        buildJarForBuildScriptClasspath(
            """
            public void t3() {
                System.out.println("bar");
            }
            """
        )
        configureProject().buildScriptNotCompiled().andOutputContains("bar")
    }

    @ToBeFixedForConfigurationCache
    @Test
    fun `recompiles buildscript on ABI change in buildscript classpath`() {
        val (className, jarPath) = buildJarForBuildScriptClasspath(
            """
            public void t4() {
                System.out.println("foo");
            }
            """
        )

        withBuildScript(
            """
            buildscript {
                dependencies { classpath(files("$jarPath")) }
            }
            $className().t4()
            """
        )
        configureProject().buildScriptCompiled().andOutputContains("foo")

        buildJarForBuildScriptClasspath(
            """
            public void t4() {
                System.out.println("bar");
            }
            public void foo() {}
            """
        )
        configureProject().buildScriptCompiled().andOutputContains("bar")
    }

    private
    fun buildJarForBuildScriptClasspath(classBody: String): Pair<String, String> {
        val baseDir = "buildscript"<commit_msg>Test Kotlin buildscript compile avoidance with non-ABI change in precompiled plugin<commit_after>package org.gradle.kotlin.dsl.integration

import org.gradle.integtests.fixtures.ToBeFixedForConfigurationCache
import org.gradle.kotlin.dsl.fixtures.AbstractKotlinIntegrationTest
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test


class BuildScriptCompileAvoidanceIntegrationTest : AbstractKotlinIntegrationTest() {

    @Before
    fun init() {
        withSettings(
            """
            rootProject.name = "test-project"
            """
        )
    }

    @Test
    fun `does not recompile buildscript on non ABI change in buildSrc`() {
        val className = givenClassInBuildSrcContains(
            """
            public void t1() {
                System.out.println("foo");
            }
            """
        )
        withBuildScript("$className().t1()")
        configureProject().buildScriptCompiled().andOutputContains("foo")

        givenClassInBuildSrcContains(
            """
            public void t1() {
                System.out.println("bar");
            }
            """
        )
        configureProject().buildScriptNotCompiled().andOutputContains("bar")
    }

    @Test
    fun `recompiles buildscript on ABI change in buildSrc`() {
        val className = givenClassInBuildSrcContains(
            """
            public void t2() {
                System.out.println("foo");
            }
            """
        )
        withBuildScript("$className().t2()")
        configureProject().buildScriptCompiled().andOutputContains("foo")

        givenClassInBuildSrcContains(
            """
            public void t2() {
                System.out.println("bar");
            }
            public void bar() {}
            """
        )
        configureProject().buildScriptCompiled().andOutputContains("bar")
    }

    @ToBeFixedForConfigurationCache
    @Test
    fun `does not recompile buildscript on non ABI change in buildscript classpath`() {
        val (className, jarPath) = buildJarForBuildScriptClasspath(
            """
            public void t3() {
                System.out.println("foo");
            }
            """
        )

        withBuildScript(
            """
            buildscript {
                dependencies { classpath(files("$jarPath")) }
            }
            $className().t3()
            """
        )
        configureProject().buildScriptCompiled().andOutputContains("foo")

        buildJarForBuildScriptClasspath(
            """
            public void t3() {
                System.out.println("bar");
            }
            """
        )
        configureProject().buildScriptNotCompiled().andOutputContains("bar")
    }

    @ToBeFixedForConfigurationCache
    @Test
    fun `recompiles buildscript on ABI change in buildscript classpath`() {
        val (className, jarPath) = buildJarForBuildScriptClasspath(
            """
            public void t4() {
                System.out.println("foo");
            }
            """
        )

        withBuildScript(
            """
            buildscript {
                dependencies { classpath(files("$jarPath")) }
            }
            $className().t4()
            """
        )
        configureProject().buildScriptCompiled().andOutputContains("foo")

        buildJarForBuildScriptClasspath(
            """
            public void t4() {
                System.out.println("bar");
            }
            public void foo() {}
            """
        )
        configureProject().buildScriptCompiled().andOutputContains("bar")
    }

    @ToBeFixedForConfigurationCache
    @Test
    fun `does not recompile buildscript on non ABI change in precompiled script plugin`() {
        val pluginId = "my-plugin"
        withPrecompiledScriptPluginInBuildSrc(
            pluginId,
            """
                println("foo")
            """
        )
        withBuildScript(
            """
                plugins {
                    id("$pluginId")
                }
            """
        )
        configureProject().buildScriptCompiled().andOutputContains("foo")

        withPrecompiledScriptPluginInBuildSrc(
            pluginId,
            """
                println("bar")
            """
        )
        configureProject().buildScriptNotCompiled().andOutputContains("bar")
    }

    private
    fun withPrecompiledScriptPluginInBuildSrc(pluginId: String, pluginSource: String) {
        withKotlinDslPluginIn("buildSrc")
        withFile("buildSrc/src/main/kotlin/$pluginId.gradle.kts", pluginSource)
    }

    private
    fun buildJarForBuildScriptClasspath(classBody: String): Pair<String, String> {
        val baseDir = "buildscript"
{'fraction_non_alphanumeric': 0.10678596328143156, 'fraction_numerical': 0.0027887520334650244, 'mean_word_length': 1.7533589251439539, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6208843', 'n_tokens_mistral': 2219, 'n_tokens_neox': 2131, 'n_words': 359}