sourceControl dependency is not added to target project

Hi, I am trying to add a dependency from Github to a project using sourceControl in settings.gradle.

My current issue is that despite there being no errors in Gradle sync, I am unable to access dependency’s code/classes. Let’s say “items” is my main project, and I am adding “cutlery” project as dependency to it.

Dependency cutlery’s settings.gradle.kts:

plugins {
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
}
rootProject.name = "cutlery"

Dependency cutlery’s build.gradle.kts:

plugins {
    kotlin("jvm") version "1.9.22"
}

group = "com.someoneelse" // # artifact id is "cutlery"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    testImplementation("org.jetbrains.kotlin:kotlin-test")
}

tasks.test {
    useJUnitPlatform()
}
kotlin {
    jvmToolchain(20)
}

Project “items”'s settings.gradle.kts:

import java.net.URI

plugins {
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
}

sourceControl {
    gitRepository(URI("ssh://git@github.com/rupinderjeet-hsphoenix/cutlery.git")) {
        producesModule("com.someoneelse:cutlery")
    }
}

rootProject.name = "items"

Project “items”'s build.gradle.kts:

plugins {
    kotlin("jvm") version "1.9.22"
}

group = "com.rupinderjeet"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {

    implementation("com.someoneelse:cutlery") {
        version {
            branch = "main"
        }
    }

    testImplementation("org.jetbrains.kotlin:kotlin-test")
}

tasks.test {
    useJUnitPlatform()
}
kotlin {
    jvmToolchain(20)
}

Project “items”'s code:

package com.rupinderjeet

import com.someoneelse.cutlery.Cutlery

fun main() {
    println("Hello World!")

    val cutlery = Cutlery()
}

Import statement has error.

This is an attempt at reproduction of similar issue I am having with my main project. It is an android app, that has several modules. One of the module wants to depend on an external GitHub dependency. The only difference from above is that in my main project, gradle sync fails with an exception:

Suppressed sync exceptions

Unknown build name: ':serverwxt (:ServerWXT)'. Known names {:=BuildId(buildRoot=/Users/~/Documents/projects/wxt), :buildSrc=BuildId(buildRoot=/Users/~/Documents/projects/wxt/buildSrc)}
java.lang.IllegalStateException: Unknown build name: ':serverwxt (:ServerWXT)'. Known names {:=BuildId(buildRoot=/Users/~/Documents/projects/wxt), :buildSrc=BuildId(buildRoot=/Users/~/Documents/projects/wxt/buildSrc)}
	at com.android.tools.idea.gradle.project.sync.ModelCacheV2ImplKt$modelCacheV2Impl$createFromDependencies$1.invoke$buildPathToBuildId(ModelCacheV2Impl.kt:565)
	at com.android.tools.idea.gradle.project.sync.ModelCacheV2ImplKt$modelCacheV2Impl$createFromDependencies$1.access$invoke$buildPathToBuildId(ModelCacheV2Impl.kt:550)
	at com.android.tools.idea.gradle.project.sync.ModelCacheV2ImplKt$modelCacheV2Impl$createFromDependencies$1$createModuleDependency$1.apply(ModelCacheV2Impl.kt:581)
	at com.android.tools.idea.gradle.project.sync.ModelCacheV2ImplKt$modelCacheV2Impl$createFromDependencies$1$createModuleDependency$1.apply(ModelCacheV2Impl.kt:580)
	at java.base/java.util.HashMap.computeIfAbsent(Unknown Source)
... 
....

more of the exception available here

In both cases, the sourceControl dependencies do get downloaded in .gradle/vcs-1 folder.

Import statement has error.

That’s because it is wrong.
Your class is at com.someoneelse.Cutlery, not com.someoneelse.cutlery.Cutlery.

Besides that, you might also consider using Included Git repositories plugin for Gradle instead of the experimental source dependencies which were never properly finished up to now.

About the IllegalStateException I have no idea, looks to be something AGP specific as the error is also coming from AGP classes. Maybe source dependencies are not compatible with Android builds? I don’t know, I don’t do Android builds and seldomly use source dependencies if at all. Maybe also here melix’ plugin would work better.

1 Like

(same person @ home)

Hi, thanks for your help.

Your class is at com.someoneelse.Cutlery, not com.someoneelse.cutlery.Cutlery.

That is very true. However, I am, also, right because IntelliJ shows me red-colored text on someoneelse since even the package com.someoneelse is not resolved yet. I added the import statement myself, becaue IDE wasn’t picking up on where the Cutlery class was at. And, I ended up using artifactId in the statement, which is an error on my part, thank you, and sorry as well.

you might also consider using Included Git repositories plugin for Gradle instead of the experimental source dependencies

Yes, I tried this but only in Android project. In non-android intellij example repositories I shared above, I thought sourceControlmight work since I saw other people using it in Github. But, fair, since it is experimental.

Maybe source dependencies are not compatible with Android builds?

You’re right, just discovered this: Google Issue Tracker

Maybe also here melix’ plugin would work better.

Well, yeah, I tried it, but let me share what I did to explain how it wasn’t working (I am just typing it in here, I will try my best to not add another typo)

I added following to settings.gradle.kts:

import me.champeau.gradle.igp.gitRepositories

plugins {
    id("me.champeau.includegit") version "0.1.6"
}

gitRepositories {
    include("libserverwxt") {
        uri.set("git@github.com:myusername/serverwxt.git")
        branch.set("trunk")
        // rootfolder/src/...
        // rootfolder/build.gradle.kts
        // rootfolder/settings.gradle.kts

        // Also, tried with following:
        includeBuild("core")
        // after changing project structure to:
        // rootfolder/core/src/...
        // rootfolder/core/build.gradle.kts
        // rootfolder/build.gradle.kts
        // rootfolder/settings.gradle.kts
    }
}

And, then, tried importing it in main project’s build.gradle.kts like this:

dependencies {
    implementation(":libserverwxt")
    // implementation("libserverwxt") // Also, tried this
    // implementation(project("libserverwxt")) // Also, tried this
}

The error was: couldn’t resolve “:libserverwxt”.

I want to ask whether my syntax or how I am trying to use melix’s plugin is correct or not. If it is correct, I guess moving to local project dependencies is my only solution, but I wanted to somehow manage/target specific version or commit-hash of local dependencies as well when using include(":localserverwxt") to avoid shipping a module from dev branch someday.

However, I am, also, right because IntelliJ shows me red-colored text on someoneelse since even the package com.someoneelse is not resolved yet.

Well, as soon as you built, it is there and also not red anymore in the IDE.
That it does not work after initial sync right away is probably due to the fact, that the feature is experimental and not properly supported.
The mentioned plugin would probably also there behave better as it builds on stable features.

The error was: couldn’t resolve “:libserverwxt”.

The plugin adds the builds as composite builds.
So you use the normal coordinates in the dependency declaration.

Btw. includeBuild("core") is majorly wrong, as core is not containing a build, but a project that is part of that other build.

1 Like

Well, as soon as you built, it is there and also not red anymore in the IDE.

Thank you, I should try this tomorrow.

Does normal coordinates mean following:

implementation("libserverwxt") 

but I remember this gives me format issue for declaring dependency. Something like groupId:artifactid:version is needed i think. Oh, as composite builds? like maybe I should try full name using groupId + artifactId + version?

Btw. includeBuild("core") is majorly wrong

Oh, thank you, I was trying to create a core module inside target githu-dependency to say that I need to import “core”. I am sure you’re right on this, but I lack the experience to deduce how, perhaps because project build has the overall artifact jar/aar since settings.gradle.kts already includes “:core”.

Something like groupId:artifactid:version is needed i think.

You can leave out :version as the dependency is served through a composite build, for that versions are ignored anyway, but other than that, yes.

perhaps because project build has the overall artifact jar/aar since settings.gradle.kts already includes “:core”

Exactly.
That build is producing the artifact with the coordinates you will request, so the necessary project in the included build is built automatically if needed.
You might want to read about composite builds in the official docs to get a bit more familiar with them, as that plugin is actually just a thing wrapper over those, doing the Git stuff and then including the build to form a composite build.
The includeBuild("core") would be necessary if in the cloned repository there were a directory core that is its own build with its own settings script. But in what you showed core was just a subproject of the build defined in the top-level settings script and should never ever ever ever be included as subproject in any other build, but only the whole build via composite build.

1 Like

Thank you so much for explaining.

And, yes, from long time, I have been meaning to learn about the build systems and how everything gets put into a package. It is interesting, and is better than me trying to try random inputs as you have seen above.

Thank you for taking the time to help me. My mind is in a better state now that I know my options, you have saved my evening. <3

1 Like