-
Notifications
You must be signed in to change notification settings - Fork 271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improved build performance by pre-creating Ivy XML files in the extracted IDE location. #1785
base: main
Are you sure you want to change the base?
Improved build performance by pre-creating Ivy XML files in the extracted IDE location. #1785
Conversation
fa28d35
to
55c3d65
Compare
...in/kotlin/org/jetbrains/intellij/platform/gradle/artifacts/transform/ExtractorTransformer.kt
Outdated
Show resolved
Hide resolved
includeGroup(Dependencies.BUNDLED_PLUGIN_GROUP) | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could create it in createDefaultRepositores()
as well, so that users have a dedicated method for this, but I thought it would be bad, because then, there we would be updating ivy & artifact path of that repo on the fly. Which is error prone, if this is exposed to customizations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually think now, that this approach is better than what was before, because previously (I have not actually tried it) if the developer did not call createDefaultRepositores()
these dependencies won't work, Which is counter intuitive, why do we allow defining dependencies which will not work. With this approach if a dependency on a bundled plugin or module is added it will work.
.listDirectoryEntries() | ||
.filter { it.isDirectory() } | ||
.mapNotNull { path -> | ||
// TODO: try not to parse all plugins at once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now it parses them only if local("/opt/ideaIU")
is used. Otherwise it is done in the transformer only once.
val pluginManager = IdePluginManager.createManager(createTempDirectory()) | ||
val plugins = platformPath.getBundledPlugins(pluginManager) | ||
|
||
for (plugin in plugins.values) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think some optimizations are possible here for caching & skipping what was already discovered, but I do not want to over complicate it. Also since it is done in the transformer now, it does not matter that much.
pathToWriteInto: Path, | ||
|
||
isCreateModules: Boolean | ||
): List<IvyModule.Dependency> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the above list of args is not something I am proud of. It is like that because I've kept things as they were as much as possible to avoid making this PR too big. It can be refactored later if needed.
...tlin/org/jetbrains/intellij/platform/gradle/extensions/IntelliJPlatformDependenciesHelper.kt
Outdated
Show resolved
Hide resolved
|
||
// For performance reasons make it exclusive. | ||
// https://docs.gradle.org/current/userguide/declaring_repositories_adv.html#declaring_content_exclusively_found_in_one_repository | ||
repositories.exclusiveContent { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is also an improvement over #1783 I noticed that there is a dedicated API for telling Gradle "look for this group only here" which is probably the safest option possible, especially if combined with prefixed groups with "com.jetbrains".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, if we pre-create that new dynamic Ivy repository here as well, we can also make it exclusive, it may save a couple of seconds on the build. But again, I am not sure that creating a repo with broken paths is something we should be doing.
c8d6d46
to
01a2617
Compare
...in/kotlin/org/jetbrains/intellij/platform/gradle/artifacts/transform/ExtractorTransformer.kt
Show resolved
Hide resolved
5117a87
to
659b1aa
Compare
cd0934e
to
a1c661f
Compare
val absNormArtifactLocationPath = artifactLocationPath?.absolute()?.normalize() | ||
|
||
// Location of Ivy files generated for the current project. | ||
val ivyPath = providers.localPlatformArtifactsPath(absNormIvyLocationPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
localPlatformArtifactsPath
does not make much sense with the dynamic repository. Should I apply it only for repositories which are static?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did that. Now the dynamic repo stores Ivy.xml files into "localPlatformArtifacts" inside platformPath
(not customisable). If a local("/path/to/ide")
is used, the customizable location is used from providers.localPlatformArtifactsPath(absNormIvyLocationPath)
private fun Path.containingDirPathStringRelativeTo(basePath: Path? = null): String { | ||
// The contract is that we are working with absolute normalized paths here. | ||
val absNormalizedPath = this.absolute().normalize() | ||
val absNormalizedBasePath = basePath?.absolute()?.normalize() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I do this very often. The reason is that I try to design functions here as independent black boxes, which should just work by themselves. It should be more fool-proof this way.
65773d4
to
5ecf8db
Compare
I think I have finally made it all work, but it seems that tests on windows fail randomly. I've seen this error first on Gradle 8.2 Win, then on Gradle 8.10.2 Win, now it is back on 8.2 Win. I do no see how my changes could have caused this. There seems to be an open bug https://youtrack.jetbrains.com/issue/KTIJ-893
|
5ecf8db
to
f65a70d
Compare
I am done with this PR, I am not planning to change anything, unless there is a feedback. I tested this very extensively on my project on both linux and windows. Also I used this to build https://github.com/InSyncWithFoo/ryecharm on linux, it works. |
@@ -71,7 +75,16 @@ data class IvyModule( | |||
* <ivy-module version="2.0"> | |||
* ... | |||
* <publications> | |||
* <artifact conf="default" ext="jar" name="/path/to/artifact.jar" type="jar" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously in all paths we had the leading slash, but the artifact pattern was already /[artifact]
which would lead to double slash eventually. It seems to work like that, but I fixed this anyway.
f0bb8cc
to
cfd2cdb
Compare
Rebased on HEAD. Also reverted one change:
|
…n. Previously it was failing with "Failed to create MD5 hash for file".
…n the list and prefixing all "fake" artifact groups with "com.jetbrains.localhost-only" and excluding that group from already declared remote repositories.
…cted IDE location.
cfd2cdb
to
f46afa5
Compare
Rebased. |
…ies because since we are creating the bundled artifacts repository lazily it is last in the list and it tried to resolve artifacts in other repos, which might lead to accidental download of a bundled plugin from the marketplace instead of taking it from the local file system.
Pull Request Details
Combines #1782 #1783 and adds another performance improvement.
Recommended to review by commits.
Description
ExtractorTransformer now pre-creates Ivy XML files in the extracted IDE location, which makes it unnecessary to load all IDE plugins, resolve their location, create Ivy XML files on every build thereafter.
Potentially this is a breaking change because bundledPlugin & bundledModule dependencies now live in a separate repository created by
IntelliJPlatformDependenciesHelper#registerIntellijPlatformIvyRepo
That repository is not customizable by the user.Related Issue
No issue.
Motivation and Context
Life is short.
How Has This Been Tested
Tests, manually. On my project also on https://github.com/InSyncWithFoo/ryecharm
Types of changes
Checklist