-
Notifications
You must be signed in to change notification settings - Fork 408
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
Support for providing sourceRoots as relative paths #3362
Conversation
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.
👍
Good idea! Instead of deserializing the whole configuration like that, you could just change the source paths to be absolute during configuration's initialization. For example, adding something like that to here: dokkaConfigurationImpl.copy(
sourceSets = dokkaConfigurationImpl.sourceSets.map {
it.copy(
sourceRoots = it.sourceRoots.map { File(it.absolutePath) }.toSet()
)
}
) Then a deserialization unit test could be added to CliTest.kt But it's optional. The integration test should hopefully be enough to catch the bugs if something changes in the analysis implementations |
Yeah, we can do it like this, but may be it's not the best idea as this will only works for CLI. While maven and Gradle now uses absolute paths, I would think, that may be we will need to change this for Gradle plugin some day. Relative paths works better regarding remote build cache, while it sounds not needed now, as mostly documentation is generated for release version, I can easily imagine cases when library published and documentation generated on every commit to master (f.e. in some closed-source project, as an API reference for other teams). And so it's better we follow all Gradle best practices. Then, there is other problem regarding converting to absolute paths eagerly which I found, but forgot to mention - we have possibility to dump configuration back to json (could be useful in Gradle) - and if doing so, we will then always dump absolute paths - which again, if we will use relative paths in Gradle will cause inconvenience, as sharing config for investigation with relative paths IMO is easier to investigate. So I would propose to stick with current approach, when we absolutise (is there such a word?) in place, where we need them to be absolute. WDYT? |
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 have not strong opinion about how Dokka should (de)serialize paths.
It seems we should not depend on how the File
stores a path.
But, as for me, a check if a file/directory is in (sub)directory is common. It can be extracted into an util function.
While maven and Gradle now uses absolute paths, I would think, that may be we will need to change this for Gradle plugin some day.
A user can define their own paths for sources.
else -> { | ||
val absolutePath = Paths.get(pathString).toAbsolutePath() | ||
sourceSet.sourceRoots.any { root -> | ||
absolutePath.startsWith(root.toPath().toAbsolutePath()) |
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 copied it from DefaultDescriptorToDocumentableTranslator.kt, but it is not the best check.
For example, let's suppose we have /home/.../src/main/kotlin
and /home/.../src/main/kotlin1
. Here we will have a false positive check since the both paths start with /home/.../src/main/kotlin
.
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.
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.
Sorry, I have not noticed it.
But can you check how it works with a shorthand (e.g. ..
)? and symbolic links?
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, yes, there is a problem that toAbsolutePath
will not remove ..
and will not follow symlinks. To remove ..
we need to use Path.normalize
and to follow symlinks and remove ..
we need to use Path.toRealPath
.
Also, Path.toRealPath
will fail if there will be some non-existent directory in the path (even if it will be removed because of ..
), while just normalize
/toAbsolutePath
- not
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've replaced Path.toAbsolutePath
with Path.toRealPath
so symlinks and ..
will be fully resolved now.
And also, as I mentioned, execution will now fail if there is some non-existent path, like in a test fixed here: 519e9ff
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.
Resolving symlinks can be excessive.
I have tested: e.g. if pathString = "/.../project/src/symlink/file.kt"
is resolved with a symlink, absolutePath
will lead to a symlink /pathToSymLink/file.kt
.
I think it would be safer to use analysisContext.modulesWithFiles[sourceModule]
in K2 for filtering. It can help to avoid problems with paths.
But it does not work in K1.
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.
Thanks, migrated to analysisContext.modulesWithFiles[sourceModule]
in 4553f98
Yep, I wasn't proposing to use it instead of the current fix, but rather in addition to it, for consistency, so that all of our runners pass absolute paths to
It's a different layer though, no? You can use relative paths in the Gradle Plugin properties, but then once the tasks are called, you have to create the common It's not a problem at the moment since At a certain point I expect we'll document |
Oops, looks like I misunderstood how Gradle works with configurations. So then yes, there is no problem here. I believe, that we need to support any kinds of paths in |
…from currently analyzed module
* Use `Path::toRealPath` to resolve symlinks and `..` in descriptors * Use `analysisContext.modulesWithFiles` in symbols
Fixes #2571
Note, that only integration test was added, as it's not easily possible to test it via unit test:
I think, that for this case, integration test will be enough, as supporting testing relative paths will cause a lot of refactoring for sole of this specific use-case.
I have also checked code around other files provided via configuration, and looks like only sourceRoots are now affected. But may be we need to add more tests for relative paths for other properties (classpath, samples, includes, etc).
One more additional note for future. First idea of mine was to make all
File
s to become absolute during deserialisation of config, but I've stumbled uponDokkaConfiguration.DokkaModuleDescription#getRelativePathToOutputDirectory
, which isFile
, but should be still relative.