I’ve got a plugin that adds dependencies, for simp...
# plugin-development
p
I’ve got a plugin that adds dependencies, for simplicity the equivalent of:
Copy code
project.configurations.maybeCreate("implementation")
project.dependencies.add("implementation", project(":my:nested:child:project"))
I’m trying to create a unit test that creates a multi-project build that tests this. But I can’t seem to create a child project, that will end up with the coordinates
":my:nested:child:project"
? For example in a unit test this code here:
Copy code
val subDir = File(rootProject.projectDir, "my/nested/child/project").also { it.mkdirs() }
val child = ProjectBuilder.builder()
    .withProjectDir(subDir)
    .withName("example-project")
    .withParent(rootProject)
    .build()
When I log out the child project in my plugin, it tells me the path is:
:example-project
if I change
withName
to:
Copy code
.withName("my:nested:child:project")
I get the error:
The project name ‘mynestedchild:project’ must not contain any of the following characters: [/, \, :, <, >, “, ?, *, |]. Set the ‘rootProject.name’ or adjust the ‘include’ statement.
What I am I missing so that I can use the coordinates
":my:nested:child:project"
to reference my sub project? (So that my coordinates are the same as a typical
build.gradle
reference
implementation project(":my:nested:child:project")
.)
c
I think...you don't need to use withProjectDir
oh wait I misread , ProjectBuilder, I was thinking on GradleRunner
I'm checking, I think you need to create all the projects (for each level)
yeah, like:
Copy code
class Test {
  @get:Rule
  val testProjectDir = TemporaryFolder()

  @Test
  fun test() {
    val subDir = File(testProjectDir.root, "my/nested/child/project").also { it.mkdirs() }
    val rootProject = ProjectBuilder.builder().withProjectDir(testProjectDir.root).build()
    val my = ProjectBuilder.builder()
      .withProjectDir(File(testProjectDir.root, "my"))
      .withName("my")
      .withParent(rootProject)
      .build()
    val child = ProjectBuilder.builder()
      .withProjectDir(subDir)
      .withName("example-project")
      .withParent(my)
      .build()

    println(child.path)
  }
}
🙌 1
Gradle does create a project for each folder, but the ProjectBuilder doesn't
p
ah ok, thanks! thats interesting that each subfolder needs to be a project
v
That's not the case. But if you include
a:b:c
, then you effectively create three projects that happen to also live in the respective directory structure by default. But you can also include
foo
and set its project directory to
a/b/c
.
p
I don’t quite understand what you mean @Vampire
v
Why not?
😅 1
p
What do you mean by “include” (vs the original question)
v
If you do
include("a:b:c")
in the settings script it is the same as doing
include("a"); include("a:b"); include("a:b:c")
. You are registering three projects
a
,
b
, and
c
that happen to live in
a/
,
a/b/
, and
a/b/c
. There is no project with name
my:nested:child:project
. There is a project with name
project
that is the child of the project
child
which is the child of the project
nested
which is the child of the project
my
. Imagine the task graph like a filesystem where
:
is the path separator.
p
Ok, so in the original question I am trying to recreate the gradle project structure. Therefore making each of the path segments a project sounds right?
v
If you don't wnat those three intermediate project, just do
include("c")
and then set the project directory of that project to be
a/b/c
. The directories don't "have to be own projects", that just the conventional default.
Ok, so in the original question I am trying to recreate the gradle project structure. Therefore making each of the path segments a project sounds right?
Definitely, Cristian was totally right. Just wanted to clarify on "all directories need to be own projects"
👍 1
p
I see. Its interesting that the convention makes each dir a project even though they are empty directorys. I would have thought the minimal project needs a file.
v
No, a project needs nothing, it is treated as if the build script would be empty.
p
💯 thats the missing bit for it to make sense 🙂 thanks
v
Also in good old days it was common to configure subprojects using
subprojects { ... }
or
allprojects { ... }
blocks, so in some projects the whole build logic was just in the root project, so no build scripts needed for the individual projects.
Which projects are part of the project is solely defined by the settings script