This message was deleted.
# community-support
s
This message was deleted.
a
it’s not a problem if Gradle sees
data
as a project, unless you’re using
allprojects {}
or
subprojects {}
?
s
Hmm, I am in fact not using these two functions, but I’ve been having some issues sometimes with how I name things and I feel like it’s been due to the fact that these directories are considered projects. I got for example
Copy code
app
|-app
|
|-notification (shouldn't be a module, just a dir)
|-|-foo (a gradle module)
|-|-bar (a gradle module)
|
|-notification-badge-data (a gradle module)
And sometimes idk if it’s gradle, or my IDE or whatever but I either get warnings in the IDE, sometimes I can’t build and gradle errors with
Copy code
Cannot find module entity for 'Module: 'app:notification-badge-data:main'.
And stuff like that. Don’t have the error in front of me now to properly copy paste just doing it from memory. So I thought maybe if I don’t get these intermediate empty modules gradle would stop complaining about stuff like this
a
ahh okay, well with subproject names like ‘main’ and ‘app’ gives me the suspicion that you might be running into this old issue: https://github.com/gradle/gradle/issues/847
Gradle discriminates between subprojects by using the group and module name. The group is set in a
build.gradle(.kts)
file with
group = "com.foo.blah"
, but the module name is inferred by the subproject directory. So if you have multiple subprojects like so…
Copy code
└── app/
    ├── notification-badge-data/
    │   └── main
    ├── prime-database/
    │   └── main
    └── x-components/
        └── main
and they all have the same group of
com.foo.blah
, then Gradle is going to get confused, because
com.foo.blah:main
could refer to any one of three subprojects…
that’s just a guess though - could you take a look and see if it makes sense?
s
Thanks a lot for the link, it really does feel close to what I am experiencing. And seeing PRs due to this issue like this one https://github.com/cashapp/redwood/pull/1113/files definitely make me feel like I need to be more careful with how I name my modules. I’ll try and not have any situation like
:bar
:bar:foo
And see if that helps 👀 Thanks a lot for helping out btw 🙏 Super appreciated.
a
you’re welcome!
ah, interesting link, thanks for sharing. I haven’t seen a technical issue with nesting ‘active’ subprojects inside ‘active’ subprojects before, but I imagine it’s risky (what happens if a plugin bugs out and decides it wants to use the ‘nested’ subproject as an output directory? It could overwrite it!)
my personal rule-of-thumb is to not nest more than 2 layers deep, and to use very specific names for the subprojects (so they’ll be alphabetically sorted). So in your case I might do something like this:
Copy code
.
└── modules/
    ├── core-app
    ├── notifications-foo
    ├── notifications-bar
    └── notifications-badge-data
s
This is a lot like what I was doing before, but browsing the directory then started looking like a shoppings list, it was way too big to be able to normally navigate through it
I really feel like adding this extra
notifications
directory only, to bundle up the gradle modules has improved navigating our gradle modules by a lot. I just don’t like that it’s fighting me sometimes when I don’t know what I’m doing 😅
I was watching this too https://www.droidcon.com/2019/11/15/android-at-scale-square/ And at 14:19 I saw this screenshot, making me feel eve more confident that this feels like a good approach. And after you enter the subdirectory, then use
-
to split modules, don’t do yet another nesting layer with any
:
in there (after :login-strategy).
👀 1
Then a bit later you see this one too. This is very specific to their needs of course, but the naming is what I am getting from this. Doing
:feature:foo-bar
where
foo-bar
is all those alternatives is probably the way to go here
Now, I still don’t know if there’s a way to make
login-strategy
not be a gradle module (if it is right now as I suspect), and if that matters or not (I would guess it does at least a little bit for configuration time etc) so if someone has more thoughts on it, like if I really shouldn’t care, of how to actually do it I’d love to hear about it!
a
I would guess it does at least a little bit for configuration time etc
I suspect an empty subproject wouldn’t be measurable, since there’s no build script or plugins to run. Unless a project uses `allprojects {}`/`subprojects {}`, which would add configuration.
anyway, yes it sounds like you have a really good idea about the strategy! If putting the notifications subprojects in a separate directory helps, then go for it. Just make sure that group and module names of all subprojects are unique, which could be done with a convention plugin. Something like this:
Copy code
// buildSrc/src/main/kotlin/my-base-convention.gradle.kts

// append the path (e.g. `:feature:foo-bar`)
group = "com.foo${project.path.replace(org.gradle.util.Path.SEPARATOR, ".")}"
thank you 2
v
You define in your settings script which projects are Gradle projects and which are not. You just have to keep in mind that
include("foo:bar")
will create foo and bar. Just do
include("bar")
and then set the project directory of that project how you want it
s
Right, so this would in fact bring the issue of names not being unique, if I tried to do something like
Copy code
include("test")
project("test").projectDir = file("feature/login-strategy")
or something like that.
Hmm I’ve come this far, I got this
Copy code
val File.gradleModuleDescendants: Sequence<File>
  get() = listFiles()
    ?.asSequence()
    ?.filter {
      it.isDirectory
    }
    ?.flatMap {
      if (File(it, "build.gradle.kts").exists()) {
        sequenceOf(it)
      } else {
        it.gradleModuleDescendants
      }
    } ?: emptySequence()

rootProject
  .projectDir
  .gradleModuleDescendants
  .forEach { file ->
    include(file.name)
    project(":${file.name}").projectDir = file
  }
Which seems to find the right directories, now I guess the only issue is with duplicate names of modules, since I am not getting any proper generated type-safe accessors, nothing gets generated.
v
Does
./gradlew projects
now give the expected list? If so, accessors in the build scripts should just work fine.
s
Yeap this actually works! Confirmed after renaming everything appropriately that
./gradlew projects
returns the right list, and then accessors just as you said worked perfectly fine. Now no need to do
projects.path.to.module
, it is just
projects.moduleName
which is what I was getting wrong before. The only tiny annoying thing that exists now is that in the IDE, it’s trying to tell me that despite the fact that the directory is called “apollo-core” for example, this is actually the “hedvigandroid.apollo-core” as far as gradle is concerned. Where “hedvigandroid” is just the root directory name of my project. Don’t know how I would get rid of that, but this is very good progress. And my snippet here did actually work 👌
👌 1
v
It is not "just the root directory", it is the root project that is the parent of your subprojects. And as it is not a direct child directory, it shows the full path to make it clear where he sits in the hierarchy. If that really concernes you, you could maybe make them standalone builds that you combine as composite build, afair that should change it, but maybe but not a good idea to make that change just for that reason. :-D
s
Aha, yeah the way you put it now it makes total sense. I agree, no need to do something like that just for the visuals, I think this is as good as it’s gonna get. Thanks a lot for the help here, super appreciated! 😊
👌 1