<commit_before>/*
 * Copyright 2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gradle.integtests.resolve

import org.gradle.integtests.fixtures.AbstractDependencyResolutionTest
import org.gradle.integtests.fixtures.FluidDependenciesResolveRunner
import org.gradle.integtests.fixtures.resolve.ResolveTestFixture
import org.junit.runner.RunWith

@RunWith(FluidDependenciesResolveRunner)
class FileDependencyResolveIntegrationTest extends AbstractDependencyResolutionTest {
    def resolve = new ResolveTestFixture(buildFile)

    def setup() {
        resolve.prepare()
    }

    def "can specify producer task for file dependency"() {
        settingsFile << "include 'sub'; rootProject.name='main'"
        buildFile << '''
            allprojects {
                configurations { compile }
                task jar {
                    doLast { 
                        file("${project.name}.jar").text = 'content' 
                    } 
                }
            }
            dependencies { 
                compile project(path: ':sub', configuration: 'compile') 
                compile files('main.jar') { builtBy jar } 
            }
            checkDeps.inputs.files configurations.compile
'''
        file("sub/build.gradle") << '''
            dependencies { 
                compile files('sub.jar') { builtBy jar } 
            }
'''

        when:
        run ":checkDeps"

        then:
        result.assertTasksExecuted(":jar", ":sub:jar", ":checkDeps");
        resolve.expectGraph {
            root(":", ":main:") {
                files << "main.jar"
                files << "sub.jar"
                project(":sub", "main:sub:") {
                    configuration = "compile"
                    noArtifacts()
                }
            }
        }
    }

    def "result includes files that match pattern at the time queried"() {
        settingsFile << "include 'sub'; rootProject.name='main'"
        buildFile << '''
            allprojects {
                configurations { compile }
                task jar {
                    doLast { 
                        file("${project.name}-1.jar").text = 'content' 
                        file("${project.name}-2.jar").text = 'content' 
                    } 
                }
            }
            dependencies { 
                compile project(path: ':sub', configuration: 'compile') 
                compile fileTree(dir: projectDir, include: '*.jar', builtBy: [jar]) 
            }
            
            // Nothing built yet, result should be empty
            assert configurations.compile.files.empty
            
            checkDeps.inputs.files configurations.compile
'''
        file("sub/build.gradle") << '''
            dependencies { 
                compile fileTree(dir: projectDir, include: '*.jar', builtBy: [jar]) 
            }
'''

        when:
        run ":checkDeps"

        then:
        result.assertTasksExecuted(":jar", ":sub:jar", ":checkDeps");
        resolve.expectGraph {
            root(":", ":main:") {
                files << "main-1.jar"
                files << "main-2.jar"
                files << "sub-1.jar"
                files << "sub-2.jar"
                project(":sub", "main:sub:") {
                    configuration = "compile"
                    noArtifacts()
                }
            }
        }
    }

    def "files referenced by file dependency are included when there is a cycle in the dependency graph"() {
        settingsFile << "include 'sub'; rootProject.name='main'"
        buildFile << '''
            allprojects {<commit_msg>Test that file collection is listed once per resolve<commit_after>/*
 * Copyright 2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gradle.integtests.resolve

import org.gradle.integtests.fixtures.AbstractDependencyResolutionTest
import org.gradle.integtests.fixtures.FluidDependenciesResolveRunner
import org.gradle.integtests.fixtures.resolve.ResolveTestFixture
import org.junit.runner.RunWith

@RunWith(FluidDependenciesResolveRunner)
class FileDependencyResolveIntegrationTest extends AbstractDependencyResolutionTest {
    def resolve = new ResolveTestFixture(buildFile)

    def setup() {
        resolve.prepare()
    }

    def "can specify producer task for file dependency"() {
        settingsFile << "include 'sub'; rootProject.name='main'"
        buildFile << '''
            allprojects {
                configurations { compile }
                task jar {
                    doLast { 
                        file("${project.name}.jar").text = 'content' 
                    } 
                }
            }
            dependencies { 
                compile project(path: ':sub', configuration: 'compile') 
                compile files('main.jar') { builtBy jar } 
            }
            checkDeps.inputs.files configurations.compile
'''
        file("sub/build.gradle") << '''
            dependencies { 
                compile files('sub.jar') { builtBy jar } 
            }
'''

        when:
        run ":checkDeps"

        then:
        result.assertTasksExecuted(":jar", ":sub:jar", ":checkDeps");
        resolve.expectGraph {
            root(":", ":main:") {
                files << "main.jar"
                files << "sub.jar"
                project(":sub", "main:sub:") {
                    configuration = "compile"
                    noArtifacts()
                }
            }
        }
    }

    def "result includes files that match pattern at the time queried"() {
        settingsFile << "include 'sub'; rootProject.name='main'"
        buildFile << '''
            allprojects {
                configurations { compile }
                task jar {
                    doLast { 
                        file("${project.name}-1.jar").text = 'content' 
                        file("${project.name}-2.jar").text = 'content' 
                    } 
                }
            }
            dependencies { 
                compile project(path: ':sub', configuration: 'compile') 
                compile fileTree(dir: projectDir, include: '*.jar', builtBy: [jar]) 
            }
            
            // Nothing built yet, result should be empty
            assert configurations.compile.files.empty
            
            checkDeps.inputs.files configurations.compile
'''
        file("sub/build.gradle") << '''
            dependencies { 
                compile fileTree(dir: projectDir, include: '*.jar', builtBy: [jar]) 
            }
'''

        when:
        run ":checkDeps"

        then:
        result.assertTasksExecuted(":jar", ":sub:jar", ":checkDeps");
        resolve.expectGraph {
            root(":", ":main:") {
                files << "main-1.jar"
                files << "main-2.jar"
                files << "sub-1.jar"
                files << "sub-2.jar"
                project(":sub", "main:sub:") {
                    configuration = "compile"
                    noArtifacts()
                }
            }
        }
    }

    def "files are requested once only when dependency is resolved"() {
        buildFile << '''
            def jarFile = file("jar-1.jar")
            jarFile << 'content'
            def libFiles = new org.gradle.api.internal.file.collections.ListBackedFileSet(jarFile) {
                Set<File> getFiles() {
                    println "FILES REQUESTED"
                    return super.getFiles()
                }
            }
            
            configurations { compile }
            dependencies { 
                compile new org.gradle.api.internal.file.collections.FileCollectionAdapter(libFiles)
            }
            
            task checkFiles {
                doLast {
                    assert configurations.compile.files == [jarFile] as Set
                }
            }
'''

        when:
        run ":checkFiles"

        then:
        output.count("FILES REQUESTED") == 1
    }

    def "files referenced by file dependency are included when there is a cycle in the dependency graph"() {
        settingsFile << "include 'sub'; rootProject.name='main'"
        buildFile << '''
            allprojects {
{'fraction_non_alphanumeric': 0.10662793199913922, 'fraction_numerical': 0.0032278889606197547, 'mean_word_length': 1.632398753894081, 'pattern_counts': {'":': 29, '<': 64, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '989652', 'n_tokens_mistral': 2372, 'n_tokens_neox': 2212, 'n_words': 598}