This message was deleted.
# dependency-management
s
This message was deleted.
r
I didn't even bother trying something like this, it would surely just crash and burn in a modern Gradle project with configuration caching and everything, right?
Hm, the
project.group
switcheroo actually does work, but my Gradle experience teaches me that using hacks is an extremely bad idea
v
Maybe a clean solution could be to have an included build that uses two configurations to get each of the jars and in one you use https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/ResolutionStrategy.html#getUseGlobalDependencySubstitutionRules-- to get the binary dependency from the repository.
r
One concern I have about using a composite build is that composite builds don't compose. I should point out that I'm not doing this for a specific project, but for many projects throughout my company, so I need something that will behave well as a custom plugin
v
What do you mean that composite builds don't compose?
r
Meaning you can't include composite builds in another composite build
v
That is years outdated knowledge. That was a restriction in the beginning of composite builds that is long gone. Works perfectly fine.
r
😮
That's an important piece of information! I thought that I read about that limitation somewhere in the documentation within the last year, but I can't find it even in the Gradle 6.0 documentation
Is there a recommended way to create an included build programmatically, without writing out build files to the filesystem?
v
I don't think I got the question
r
You suggested:
Maybe a clean solution could be too have an included build that uses two configurations to get each of the jars
How would I do this from a plugin?
v
You don't
r
@melix Any other ideas?
The
getUseGlobalDependencySubstitutionRules
appears to target this use case
Bingo, just gotta figure out how to use it
@Jendrik Johannes Is this feature expected to work within the current module, so that a project can obtain its own previously published jar file? The integration tests don't appear to test that case
v
According to documentation it does not, that's why I said you need to use a composite build together with it
j
Yes. Sadly it does not work with the current module. Because the current module (the root) has such a special handling in dependency resolution. You would have to do the comparison from another module. (
getUseGlobalDependencySubstitutionRules
may still be helpful then, but is only needed if you also use included builds.)
v
Can you do it somehow without a composite build @Jendrik Johannes?
r
Because the current module (the root) has such a special handling in dependency resolution
This is what I was wondering: does the root module even have a dependency substitution rule, or is it special-cased somewhere?
j
It is special-cased (by the way some code in the resolution engine has evolved starting with Gradle 0.1, where some of the code was copied from Ivy šŸ˜„ )
šŸ˜† 1
Can you do it somehow without a composite build
In a single build you don't necessarily have substitutions for the subprojects. But I keep forgetting the details. I think if you don't add any substitution rules, projects and published versions can both be selected and the normal version conflict resolution (higher version wins) is used.
r
In my experiments, a dependency on
my-group:my-project
will always resolve to the current module, irrespective of version (and irrespective of
resolutionStrategy
)
j
There is
Copy code
resolutionStrategy.preferProjectModules()
to always select the local project
But if you don't turn that on, I think you can make it select a published version instead. But there is no strategy to "always select the published version".
Maybe it works with a strict version that points at the published version you want to select (?)
r
Nah, tried that. The
!!
syntax, right? It still resolves to the current module
j
Looks like this feature request is still open: https://github.com/gradle/gradle/issues/1629
r
The hilarious thing is that you can set
project.group
to some other value, perform the dependency resolution (eagerly), and then restore the old value; that works fine!
j
But I am sure that you somehow can get the published version selected.... at least it was possible at some point in the past (that's why
preferProjectModules
was introduced)
r
Looks like you can
force
a dependency edge
j
Then maybe the cleanest (?) setup would then be to use an extra build and include the one for which you want to do the comparison. Then you can use
getUseGlobalDependencySubstitutionRules
to make a clear decisions. But maybe that's overkill for your setup...
r
I work in my company's developer tooling division. I'm not trying to solve this problem for a single build, but for basically all builds. I need a packaged solution I can vend, probably some sort of plugin
And I don't think an extra build can be created programmatically; it would require additional files, checked in to git
So if I can't do this through Gradle, I'll whip out an HTTP client and do it myself. I'd prefer to not have to do that
j
The hilarious thing is that you can set
project.group
....
Maybe this "hack" isn't too bad then. If it works. Change the group, fetch the previous version, set the group back.
Imo it's a missing feature in Gradle and that would justify using such a workaround for me.
r
I've learned that Gradle plugin development goes much more smoothly when you do everything strictly by the book and don't get creative with hacks...
But first I'm going to look into this:
Copy code
dependencies.create(
            group = "com.plexxi",
            name = "PlexxiCore",
            version = "${project.property(DbProps.REFERENCE_VERSION_PROP)}",
            ext = "war").apply {
            isForce = true
        }
Setting
isForce = true
is a fresh idea I haven't tried yet
šŸ‘ 1
j
I found the original "design doc" and one of the original posts from the forum which let to the introduction of
preferProjectModules
back in the day. I don't know if this helps, but maybe: • https://github.com/gradle/gradle/blob/82d482df8192dba085dd6f8b06bad4f41e805753/design-docs/dependency-management-projectpriority.md • https://discuss.gradle.org/t/project-dependencies-participate-in-conflict-resolution/18875
r
FYI this Javadoc in
ExternalDependency
is garbled:
Copy code
@deprecated Use {@link MutableVersionConstraint#strictly(String) instead.}
It renders as:
isForce
has no effect, it's just another form of version syntax. I'm currently looking at using
ArtifactResolutionQuery
Looks like that API can only be used to obtain sources and stuff
OK, I've stepped through the code and concluded that this behavior is hardcoded into the graph resolution logic. @Jendrik Johannes, this is why setting strict versions, forcing versions, etc doesn't do anything. See in particular this commit, which specifically prevents "selection" from being deferred on the root module; it is performed as soon as the graph is constructed. Here, "selection" refers to the eviction of all other versions of the root module (see
ModuleResolveState#select
). This all happens early during the process of graph resolution, before artifact resolution can run, and it's a fixed behavior that is unaffected by any public APIs I'm aware of.
@Louis Jacomet Why this commit? It's tagged with
groovy-4-compile-problem
, but that's all I know
For anyone coming across this thread in the future: I caved and used the
project.group
hack. I figured the code in question was unlikely to change in a way that would suddenly break this approach, given its age, complexity, and overall design
šŸ‘ 1