Skip to content

Commit

Permalink
Expose BuildLayout root dir from ProjectLayout
Browse files Browse the repository at this point in the history
Issue: #26521
  • Loading branch information
abstratt committed Apr 22, 2024
1 parent 30a7dfa commit 3f8dc7d
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.gradle.api.file;

import org.gradle.api.Incubating;
import org.gradle.api.Project;
import org.gradle.api.provider.Provider;
import org.gradle.internal.service.scopes.Scope;
Expand All @@ -38,6 +39,14 @@ public interface ProjectLayout {
*/
Directory getProjectDirectory();

/**
* Returns the root build directory.
*
* @since 8.5
*/
@Incubating
Directory getRootDirectory();

/**
* Returns the build directory for the project.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,32 @@ import org.gradle.integtests.fixtures.AbstractIntegrationSpec
class ProjectLayoutIntegrationTest extends AbstractIntegrationSpec {
private static final String STRING_CALLABLE = 'new java.util.concurrent.Callable<String>() { String call() { return "src/resource/file.txt" } }'

def "can access the project dir and build dir"() {
buildFile """
def "can access the project layout dirs"() {
def rootDir = testDirectory
def projectDir = rootDir.createDir("main")
def buildDir1 = projectDir.createDir("build")
def buildDir2 = projectDir.createDir("output")

groovyFile(rootDir.file("settings.gradle"), """
include("main")
""")
groovyFile(projectDir.file("build.gradle"), """
println "project dir: " + layout.projectDirectory.asFile
println "root dir: " + layout.rootDirectory.asFile
def b = layout.buildDirectory
println "build dir: " + b.get()
buildDir = "output"
println "build dir 2: " + b.get()
"""
""")

when:
run()

then:
outputContains("project dir: " + testDirectory)
outputContains("build dir: " + testDirectory.file("build"))
outputContains("build dir 2: " + testDirectory.file("output"))
outputContains("project dir: " + projectDir)
outputContains("root dir: " + rootDir)
outputContains("build dir: " + buildDir1)
outputContains("build dir 2: " + buildDir2)
}

def "can apply convention to build dir"() {
Expand Down Expand Up @@ -94,57 +104,52 @@ class ProjectLayoutIntegrationTest extends AbstractIntegrationSpec {
outputContains("task build dir: " + testDirectory.file("output"))
}

def "can define and resolve calculated directory relative to project and build directory"() {
buildFile """
def "can define and resolve calculated locations relative to project, build and root directory"() {
def rootDir = testDirectory
def projectDir = rootDir.createDir("main")

groovyFile(rootDir.file("settings.gradle"), """
include("main")
""")
groovyFile(projectDir.file("build.gradle"), """
def childDirName = "child"
def srcDir = layout.projectDir.dir("src").dir(providers.provider { childDirName })
def outputDir = layout.buildDirectory.dir(providers.provider { childDirName })
def rootDocDir = layout.rootDirectory.dir("docs").dir(providers.provider { childDirName })
println "docs dir 1: " + rootDocDir.get()
println "src dir 1: " + srcDir.get()
println "output dir 1: " + outputDir.get()
buildDir = "output/some-dir"
childDirName = "other-child"
println "docs dir 2: " + rootDocDir.get()
println "src dir 2: " + srcDir.get()
println "output dir 2: " + outputDir.get()
"""
""")

when:
run()

then:
outputContains("src dir 1: " + testDirectory.file("src/child"))
outputContains("output dir 1: " + testDirectory.file("build/child"))
outputContains("src dir 2: " + testDirectory.file("src/other-child"))
outputContains("output dir 2: " + testDirectory.file("output/some-dir/other-child"))
outputContains("docs dir 1: " + testDirectory.file("docs/child"))
outputContains("src dir 1: " + testDirectory.file("main/src/child"))
outputContains("output dir 1: " + testDirectory.file("main/build/child"))
outputContains("docs dir 2: " + testDirectory.file("docs/other-child"))
outputContains("src dir 2: " + testDirectory.file("main/src/other-child"))
outputContains("output dir 2: " + testDirectory.file("main/output/some-dir/other-child"))
}

def "can define and resolve calculated file relative to project and build directory"() {
buildFile """
def childDirName = "child"
def srcFile = layout.projectDir.dir("src").file(providers.provider { childDirName })
def outputFile = layout.buildDirectory.file(providers.provider { childDirName })
println "src file 1: " + srcFile.get()
println "output file 1: " + outputFile.get()
buildDir = "output/some-dir"
childDirName = "other-child"
println "src file 2: " + srcFile.get()
println "output file 2: " + outputFile.get()
"""

when:
run()

then:
outputContains("src file 1: " + testDirectory.file("src/child"))
outputContains("output file 1: " + testDirectory.file("build/child"))
outputContains("src file 2: " + testDirectory.file("src/other-child"))
outputContains("output file 2: " + testDirectory.file("output/some-dir/other-child"))
}
def "can use file() method to resolve locations created relative to the project layout dirs"() {
def rootDir = testDirectory
def projectDir = rootDir.createDir("sub")
def "can use file() method to resolve locations created relative to the project dir and build dir"() {
buildFile << """
groovyFile(rootDir.file("settings.gradle"), """
include("sub")
""")
groovyFile(projectDir.file("build.gradle"), """
def location = $expression
println "location: " + file(location)
"""
""")
when:
run()
Expand All @@ -153,15 +158,17 @@ class ProjectLayoutIntegrationTest extends AbstractIntegrationSpec {
outputContains("location: " + testDirectory.file(resolvesTo))
where:
expression | resolvesTo
"layout.projectDirectory.dir('src/main/java')" | "src/main/java"
"layout.projectDirectory.dir(providers.provider { 'src/main/java' })" | "src/main/java"
"layout.projectDirectory.file('src/main/java')" | "src/main/java"
"layout.projectDirectory.file(providers.provider { 'src/main/java' })" | "src/main/java"
"layout.buildDirectory.dir('classes/main')" | "build/classes/main"
"layout.buildDirectory.dir(providers.provider { 'classes/main' })" | "build/classes/main"
"layout.buildDirectory.file('classes/main')" | "build/classes/main"
"layout.buildDirectory.file(providers.provider { 'classes/main' })" | "build/classes/main"
expression | resolvesTo
"layout.projectDirectory.dir('src/main/java')" | "sub/src/main/java"
"layout.projectDirectory.dir(providers.provider { 'src/main/java' })" | "sub/src/main/java"
"layout.projectDirectory.file('src/main/java')" | "sub/src/main/java"
"layout.projectDirectory.file(providers.provider { 'src/main/java' })" | "sub/src/main/java"
"layout.rootDirectory.file(providers.provider { 'docs' })" | "docs"
"layout.rootDirectory.file(providers.provider { 'docs/readme.md' })" | "docs/readme.md"
"layout.buildDirectory.dir('classes/main')" | "sub/build/classes/main"
"layout.buildDirectory.dir(providers.provider { 'classes/main' })" | "sub/build/classes/main"
"layout.buildDirectory.file('classes/main')" | "sub/build/classes/main"
"layout.buildDirectory.file(providers.provider { 'classes/main' })" | "sub/build/classes/main"
}
def "can construct file collection containing locations created relative to the project dir and build dir"() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.gradle.api.internal.tasks.TaskDependencyFactory;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.util.PatternSet;
import org.gradle.initialization.layout.BuildLocations;
import org.gradle.internal.Factory;

import java.io.File;
Expand All @@ -45,8 +46,9 @@ public class DefaultProjectLayout implements ProjectLayout, TaskFileVarFactory {
private final PropertyHost propertyHost;
private final FileCollectionFactory fileCollectionFactory;
private final FileFactory fileFactory;
private final Directory rootBuildDir;

public DefaultProjectLayout(File projectDir, FileResolver fileResolver, TaskDependencyFactory taskDependencyFactory, Factory<PatternSet> patternSetFactory, PropertyHost propertyHost, FileCollectionFactory fileCollectionFactory, FilePropertyFactory filePropertyFactory, FileFactory fileFactory) {
public DefaultProjectLayout(File projectDir, FileResolver fileResolver, TaskDependencyFactory taskDependencyFactory, Factory<PatternSet> patternSetFactory, PropertyHost propertyHost, FileCollectionFactory fileCollectionFactory, FilePropertyFactory filePropertyFactory, FileFactory fileFactory, BuildLocations buildLocations) {
this.fileResolver = fileResolver;
this.taskDependencyFactory = taskDependencyFactory;
this.patternSetFactory = patternSetFactory;
Expand All @@ -55,6 +57,12 @@ public DefaultProjectLayout(File projectDir, FileResolver fileResolver, TaskDepe
this.fileFactory = fileFactory;
this.projectDir = fileFactory.dir(projectDir);
this.buildDir = filePropertyFactory.newDirectoryProperty().convention(fileFactory.dir(fileResolver.resolve(Project.DEFAULT_BUILD_DIR_NAME)));
this.rootBuildDir = fileFactory.dir(buildLocations.getRootDirectory());
}

@Override
public Directory getRootDirectory() {
return rootBuildDir;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.tasks.util.PatternSet;
import org.gradle.cache.UnscopedCacheBuilderFactory;
import org.gradle.cache.internal.DecompressionCacheFactory;
import org.gradle.cache.internal.scopes.DefaultProjectScopedCacheBuilderFactory;
import org.gradle.cache.scopes.ProjectScopedCacheBuilderFactory;
import org.gradle.cache.scopes.ScopedCacheBuilderFactory;
import org.gradle.initialization.layout.BuildLocations;
import org.gradle.internal.Factory;
import org.gradle.internal.file.Deleter;
import org.gradle.internal.file.PathToFileResolver;
Expand Down Expand Up @@ -146,7 +152,7 @@ ObjectFactory createObjectFactory(InstantiatorFactory instantiatorFactory, Servi
}

DefaultProjectLayout createProjectLayout(FileResolver fileResolver, FileCollectionFactory fileCollectionFactory, TaskDependencyFactory taskDependencyFactory,
FilePropertyFactory filePropertyFactory, Factory<PatternSet> patternSetFactory, PropertyHost propertyHost, FileFactory fileFactory) {
return new DefaultProjectLayout(projectDir, fileResolver, taskDependencyFactory, patternSetFactory, propertyHost, fileCollectionFactory, filePropertyFactory, fileFactory);
FilePropertyFactory filePropertyFactory, Factory<PatternSet> patternSetFactory, PropertyHost propertyHost, FileFactory fileFactory, BuildLocations buildLocations) {
return new DefaultProjectLayout(projectDir, fileResolver, taskDependencyFactory, patternSetFactory, propertyHost, fileCollectionFactory, filePropertyFactory, fileFactory, buildLocations);
}
}

0 comments on commit 3f8dc7d

Please sign in to comment.