[gradle][IDEA-378369] remove 'Download Sources' button from the quick doc popup

GitOrigin-RevId: 13b60ddecbab86878acff576e59a3145b5670279
This commit is contained in:
Alexander.Glukhov
2025-12-18 22:49:27 +00:00
committed by intellij-monorepo-bot
parent 69e6d960c6
commit feca4c4016
14 changed files with 7 additions and 420 deletions
@@ -18,7 +18,6 @@ public interface DocumentationMarkup {
@ApiStatus.Internal String CLASS_CENTERED = "centered";
@ApiStatus.Internal String CLASS_BOTTOM = "bottom";
@ApiStatus.Internal String CLASS_TOP = "top";
@ApiStatus.Internal String CLASS_DOWNLOAD_DOCUMENTATION = "download-documentation";
@NlsSafe String DEFINITION_START = "<div class='" + CLASS_DEFINITION + "'><pre>";
@NlsSafe String DEFINITION_END = "</pre></div>";
@@ -576,7 +576,6 @@ tooltip.computing.classes.for.auto.import=Computing classes to auto-import\u2026
jvm.inspections.dependency.configure.button.text=Configure dependency rules
checking.code.highlightings.in.background=Loading Code Highlighting
title.checking.code.highlightings.in.background.task=Loading code passes
documentation.download.button.label=Download documentation
command.completion.title=Commands
command.completion.filter.hint=press ''{0}'' to show commands
command.completion.project.tool.text=Project tool
@@ -119,7 +119,7 @@ object DocumentationHtmlUtil {
padding: 0 ${contentInnerPadding}px 0px ${contentInnerPadding}px;
max-width: 100%;
}
.$CLASS_BOTTOM, .$CLASS_DOWNLOAD_DOCUMENTATION, .$CLASS_TOP {
.$CLASS_BOTTOM, .$CLASS_TOP {
padding: ${beforeSpacing}px ${contentInnerPadding}px ${afterSpacing}px ${contentInnerPadding}px;
}
.$CLASS_SECTIONS { padding: 0 ${contentInnerPadding - 2}px 0 ${contentInnerPadding - 2}px 0; border-spacing: 0; }
@@ -83,7 +83,6 @@ import org.jetbrains.annotations.*;
import org.jetbrains.concurrency.CancellablePromise;
import org.jetbrains.concurrency.Promises;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.TextNode;
import javax.swing.*;
import java.awt.*;
@@ -1821,7 +1820,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Nullable DocumentationProvider provider
) {
HtmlChunk locationInfo = getDefaultLocationInfo(element);
return decorate(text, locationInfo, getExternalText(element, externalUrl, provider), null);
return decorate(text, locationInfo, getExternalText(element, externalUrl, provider));
}
@RequiresReadLock
@@ -1861,8 +1860,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Internal
@Contract(pure = true)
public static @Nls String decorate(@Nls @NotNull String text, @Nullable HtmlChunk location, @Nullable HtmlChunk links,
@Nullable String downloadDocumentationActionLink) {
public static @Nls String decorate(@Nls @NotNull String text, @Nullable HtmlChunk location, @Nullable HtmlChunk links) {
text = StringUtil.replaceIgnoreCase(text, "</html>", "");
text = StringUtil.replaceIgnoreCase(text, "</body>", "");
@@ -1883,18 +1881,6 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
DocumentationHtmlUtil.removeEmptySections$intellij_platform_lang_impl(document);
if (downloadDocumentationActionLink != null) {
document.body().appendChild(
new Element("div")
.addClass(CLASS_DOWNLOAD_DOCUMENTATION)
.appendChildren(Arrays.asList(
new Element("icon").attr("src", "AllIcons.Plugins.Downloads"),
new TextNode(" "),
new Element("a").attr("href", downloadDocumentationActionLink)
.text(CodeInsightBundle.message("documentation.download.button.label"))
)));
}
if (location != null) {
document.body().append(getBottom().child(location).toString());
}
@@ -1914,7 +1900,6 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
&& (
nextSibling.hasClass(CLASS_SECTIONS)
|| nextSibling.hasClass(CLASS_BOTTOM)
|| nextSibling.hasClass(CLASS_DOWNLOAD_DOCUMENTATION)
))) {
div.after(new Element("hr"));
}
@@ -1,25 +0,0 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.documentation.actions
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Experimental
interface DocumentationDownloader {
suspend fun canHandle(project: Project, file: VirtualFile): Boolean
suspend fun download(project: Project, file: VirtualFile): Boolean
companion object {
val EP = ExtensionPointName.create<DocumentationDownloader>("com.intellij.documentation.documentationDownloader")
const val HREF_PREFIX = "download_sources:"
fun formatLink(target: VirtualFile?): String? {
val virtualFileUrl: String = target?.url ?: return null
return HREF_PREFIX + virtualFileUrl
}
}
}
@@ -1,21 +1,16 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.lang.documentation.ide.impl
import com.intellij.codeInsight.documentation.actions.DocumentationDownloader
import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.lang.documentation.ide.impl.DocumentationUsageCollector.logDownloadFinished
import com.intellij.lang.documentation.ide.ui.DocumentationUI
import com.intellij.lang.documentation.ide.ui.UISnapshot
import com.intellij.model.Pointer
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.EDT
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.IndexNotReadyException
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.OrderEntry
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.platform.backend.documentation.DocumentationTarget
import com.intellij.platform.backend.documentation.impl.DocumentationRequest
import com.intellij.platform.backend.documentation.impl.InternalLinkResult
@@ -120,11 +115,6 @@ internal class DocumentationBrowser private constructor(
}
private suspend fun handleLinkRequest(url: String) {
if (url.startsWith(DocumentationDownloader.HREF_PREFIX)) {
handleDownloadSourcesRequest(url)
return
}
val targetPointer = this.targetPointer
val internalResult = try {
handleLink(project, targetPointer, url, page)
@@ -159,22 +149,6 @@ internal class DocumentationBrowser private constructor(
}
}
private fun handleDownloadSourcesRequest(href: String) {
val filePath = href.replaceFirst(DocumentationDownloader.HREF_PREFIX, "")
val file = VirtualFileManager.getInstance().findFileByUrl(filePath)
if (file != null) {
CoroutineScopeService.getCoroutineScope(project)
.launch {
val handler = DocumentationDownloader.EP.extensionList.find { it.canHandle(project, file) }
if (handler != null) {
val success = handler.download(project, file)
logDownloadFinished(project, handler::class.java, success)
}
}
closeTrigger?.invoke()
}
}
private suspend fun handleRestoreRequest(snapshot: HistorySnapshot) {
val page = snapshot.page
val restored = page.restorePage(snapshot.ui)
@@ -220,13 +194,4 @@ internal class DocumentationBrowser private constructor(
*/
suspend fun DocumentationBrowser.waitForContent(): Boolean = pageFlow.first().waitForContent()
}
@Service(Service.Level.PROJECT)
private class CoroutineScopeService(val coroutineScope: CoroutineScope) {
companion object {
fun getCoroutineScope(project: Project): CoroutineScope {
return project.service<CoroutineScopeService>().coroutineScope
}
}
}
}
@@ -3,21 +3,17 @@
package com.intellij.lang.documentation.ide.impl
import com.intellij.codeInsight.documentation.actions.DocumentationDownloader
import com.intellij.lang.documentation.ide.ui.ExpandableDefinition
import com.intellij.lang.documentation.ide.ui.UISnapshot
import com.intellij.lang.documentation.ide.ui.UIState
import com.intellij.lang.documentation.ide.ui.createExpandableDefinition
import com.intellij.openapi.application.readAction
import com.intellij.openapi.project.IndexNotReadyException
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.platform.backend.documentation.ContentUpdater
import com.intellij.platform.backend.documentation.DocumentationContentData
import com.intellij.platform.backend.documentation.LinkData
import com.intellij.platform.backend.documentation.impl.DocumentationRequest
import com.intellij.platform.backend.documentation.impl.computeDocumentation
import com.intellij.psi.PsiElement
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
@@ -68,17 +64,8 @@ internal class DocumentationPage(val requests: List<DocumentationRequest>, val p
}
}
private suspend fun prepareContent(content: DocumentationContentData, links: LinkData, uiState: UIState?): DocumentationPageContent.Content {
var downloadSourcesLink: String? = null
if (content.targetElement != null) {
val targetFile = readAction { content.targetElement.getTargetFile() }
if (targetFile != null) {
if (DocumentationDownloader.EP.extensionList.find { it.canHandle(project, targetFile) } != null) {
downloadSourcesLink = DocumentationDownloader.formatLink(targetFile)
}
}
}
return DocumentationPageContent.Content(content, links, uiState, downloadSourcesLink)
private fun prepareContent(content: DocumentationContentData, links: LinkData, uiState: UIState?): DocumentationPageContent.Content {
return DocumentationPageContent.Content(content, links, uiState)
}
/**
@@ -115,10 +102,6 @@ internal class DocumentationPage(val requests: List<DocumentationRequest>, val p
}
}
}
private fun PsiElement.getTargetFile(): VirtualFile? = containingFile?.run {
virtualFile ?: originalFile.virtualFile
}
}
internal sealed class DocumentationPageContent {
@@ -129,6 +112,5 @@ internal sealed class DocumentationPageContent {
val content: DocumentationContentData,
val links: LinkData,
val uiState: UIState?,
val downloadSourcesLink: String?
) : DocumentationPageContent()
}
@@ -1,24 +1,17 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.lang.documentation.ide.impl
import com.intellij.codeInsight.documentation.actions.DocumentationDownloader
import com.intellij.internal.statistic.eventLog.EventLogGroup
import com.intellij.internal.statistic.eventLog.events.EventFields
import com.intellij.internal.statistic.eventLog.events.EventId2
import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector
import com.intellij.lang.documentation.psi.PsiElementDocumentationTarget
import com.intellij.openapi.project.Project
import com.intellij.platform.backend.documentation.DocumentationTarget
object DocumentationUsageCollector : CounterUsagesCollector() {
override fun getGroup(): EventLogGroup = GROUP
private val GROUP = EventLogGroup("documentation", 5)
private val DOWNLOAD_FINISHED_EVENT = GROUP.registerEvent("quick.doc.download.finished",
EventFields.Class("handler"),
EventFields.Boolean("success")
)
private val GROUP = EventLogGroup("documentation", 6)
val QUICK_DOC_SHOWN = GROUP.registerEvent("quick.doc.shown", EventFields.FileType)
val QUICK_DOC_CLOSED = GROUP.registerEvent("quick.doc.closed", EventFields.FileType, EventFields.Boolean("joint"), EventFields.DurationMs)
@@ -32,10 +25,6 @@ object DocumentationUsageCollector : CounterUsagesCollector() {
EventFields.Enum("protocol", DocumentationLinkProtocol::class.java),
EventFields.Boolean("lookup_active"),
)
fun logDownloadFinished(project: Project, handlerClass: Class<out DocumentationDownloader>, success: Boolean) {
DOWNLOAD_FINISHED_EVENT.log(project, handlerClass, success)
}
}
internal fun getClassRefForStatistics(dereference: DocumentationTarget?): Class<out Any>? {
@@ -293,7 +293,7 @@ internal class DocumentationUI(
imageResolver = content.imageResolver
val linkChunk = linkChunk(presentation.presentableText, pageContent.links)
val decoratedData = extractAdditionalData(content.html)
val decorated = decorate(decoratedData?.html ?: content.html, null, linkChunk, pageContent.downloadSourcesLink)
val decorated = decorate(decoratedData?.html ?: content.html, null, linkChunk)
if (!updateContent(decorated, presentation, ContentKind.DocumentationPage, decoratedData?.decoratedStyle)) {
return
}
@@ -601,8 +601,6 @@
<extensionPoint name="elementPreviewProvider" interface="com.intellij.codeInsight.preview.ElementPreviewProvider" dynamic="true"/>
<extensionPoint name="testActionProvider" interface="com.intellij.execution.testframework.ToggleModelActionProvider" dynamic="true"/>
<extensionPoint name="documentation.documentationDownloader"
interface="com.intellij.codeInsight.documentation.actions.DocumentationDownloader" dynamic="true"/>
<extensionPoint name="testDiffProvider" beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
<with attribute="implementationClass" implements="com.intellij.execution.testframework.actions.TestDiffProvider"/>
@@ -1,32 +0,0 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.gradle.codeInsight.documentation
import com.intellij.codeEditor.JavaEditorFileSwapper
import com.intellij.codeInsight.documentation.actions.DocumentationDownloader
import com.intellij.ide.highlighter.JavaClassFileType
import com.intellij.openapi.application.readAction
import com.intellij.openapi.fileTypes.FileTypeRegistry
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.plugins.gradle.service.sources.GradleLibrarySourcesDownloader
import org.jetbrains.plugins.gradle.settings.GradleSettings
class GradleDocumentationDownloader : DocumentationDownloader {
override suspend fun canHandle(project: Project, file: VirtualFile): Boolean {
if (!FileTypeRegistry.getInstance().isFileOfType(file, JavaClassFileType.INSTANCE)) {
return false
}
if (GradleSettings.getInstance(project).linkedProjectsSettings.isEmpty()) {
return false
}
if (!GradleLibrarySourcesDownloader.canDownloadSources(project, file)) {
return false
}
return readAction { JavaEditorFileSwapper.findSourceFile(project, file) == null }
}
override suspend fun download(project: Project, file: VirtualFile): Boolean {
return GradleLibrarySourcesDownloader.download(project, file) != null
}
}
@@ -1,153 +0,0 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.gradle.service.sources
import com.intellij.ide.highlighter.JavaClassFileType
import com.intellij.jarFinder.InternetAttachSourceProvider.attachSourceJar
import com.intellij.openapi.application.EDT
import com.intellij.openapi.application.readAction
import com.intellij.openapi.externalSystem.model.project.LibraryPathType
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.fileTypes.FileTypeRegistry
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.containers.ContainerUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.future.await
import kotlinx.coroutines.withContext
import org.jetbrains.plugins.gradle.execution.build.CachedModuleDataFinder
import org.jetbrains.plugins.gradle.execution.target.maybeGetLocalValue
import org.jetbrains.plugins.gradle.service.GradleInstallationManager
import org.jetbrains.plugins.gradle.service.cache.GradleLocalCacheHelper
import org.jetbrains.plugins.gradle.util.*
import java.nio.file.Path
import java.util.*
object GradleLibrarySourcesDownloader {
suspend fun canDownloadSources(project: Project, file: VirtualFile): Boolean {
if (!file.isClassFile()) {
return false
}
val entries = findLibraryEntriesForFile(project, file)
if (entries.isEmpty()) {
return false
}
return canDownloadSources(entries)
}
fun canDownloadSources(orderEntries: List<LibraryOrderEntry>): Boolean {
return findAssociatedGradleModule(orderEntries) != null
}
suspend fun download(project: Project, file: VirtualFile): Path? =
download(project, file, DefaultGradleDependencySourceDownloaderErrorHandler)
suspend fun download(project: Project, file: VirtualFile, errorHandler: GradleDependencySourceDownloaderErrorHandler): Path? {
if (!file.isClassFile()) {
return null
}
val libraryEntries = findLibraryEntriesForFile(project, file)
return download(project, libraryEntries, errorHandler)
}
suspend fun download(project: Project, orderEntries: List<LibraryOrderEntry>): Path? =
download(project, orderEntries, DefaultGradleDependencySourceDownloaderErrorHandler)
suspend fun download(
project: Project,
orderEntries: List<LibraryOrderEntry>,
errorHandler: GradleDependencySourceDownloaderErrorHandler,
): Path? {
if (orderEntries.isEmpty()) {
return null
}
val module = findAssociatedGradleModule(orderEntries) ?: return null
val gradleModuleData = CachedModuleDataFinder.getGradleModuleData(module) ?: return null
val externalProjectPath = gradleModuleData.moduleData.linkedExternalProjectPath ?: return null
val libraryOrderEntry = orderEntries.first()
val sourceArtifactNotation = libraryOrderEntry.getArtifactCoordinates()?.let { "$it:sources" } ?: return null
val cachedSourcesPath = lookupSourcesPathFromCache(libraryOrderEntry, sourceArtifactNotation, project, externalProjectPath)
if (cachedSourcesPath != null && isValidJar(cachedSourcesPath)) {
attachSources(cachedSourcesPath, orderEntries)
return cachedSourcesPath
}
val path = GradleArtifactDownloader.downloadArtifact(
project,
GradleBundle.message("gradle.action.download.sources"),
sourceArtifactNotation,
externalProjectPath,
errorHandler
).await()
if (path != null) {
attachSources(path, orderEntries)
}
return path
}
private suspend fun attachSources(sourcesJar: Path, orderEntries: List<LibraryOrderEntry>) {
withContext(Dispatchers.EDT) {
val libraries = HashSet<Library>()
orderEntries.forEach {
ContainerUtil.addIfNotNull(libraries, it.library)
}
attachSourceJar(sourcesJar, libraries)
}
}
private fun lookupSourcesPathFromCache(
libraryOrderEntry: LibraryOrderEntry,
sourceArtifactNotation: String,
project: Project,
projectPath: String,
): Path? {
val rootFiles = libraryOrderEntry.getRootFiles(OrderRootType.CLASSES)
if (rootFiles.size == 0) {
return null
}
val buildLayoutParameters = GradleInstallationManager.getInstance().guessBuildLayoutParameters(project, projectPath)
val gradleUserHome = buildLayoutParameters.gradleUserHomePath.maybeGetLocalValue()
if (gradleUserHome == null) {
return null
}
val filePath = Path.of(rootFiles[0].path)
if (!filePath.startsWith(gradleUserHome)) {
return null
}
val coordinates = getLibraryUnifiedCoordinates(sourceArtifactNotation)
if (coordinates == null) {
return null
}
val localArtifacts = GradleLocalCacheHelper.findArtifactComponents(
coordinates,
gradleUserHome,
EnumSet.of(LibraryPathType.SOURCE)
)
return localArtifacts[LibraryPathType.SOURCE]?.firstOrNull()
}
private fun findAssociatedGradleModule(libraryOrderEntries: List<LibraryOrderEntry>): Module? {
return libraryOrderEntries
.filter { !it.isModuleLevel }
.map { it.ownerModule }
.find { ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, it) }
}
private fun VirtualFile.isClassFile(): Boolean {
val registry = FileTypeRegistry.getInstance()
return registry.isFileOfType(this, JavaClassFileType.INSTANCE)
}
private suspend fun findLibraryEntriesForFile(project: Project, file: VirtualFile): List<LibraryOrderEntry> {
return readAction {
val index = ProjectFileIndex.getInstance(project)
return@readAction index.getOrderEntriesForFile(file)
.filterIsInstance<LibraryOrderEntry>()
.toList()
}
}
}
@@ -1,46 +0,0 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:JvmName("ArtifactCoordinatesUtil")
package org.jetbrains.plugins.gradle.service.sources
import com.intellij.buildsystem.model.unified.UnifiedCoordinates
import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.OrderRootType
import org.jetbrains.annotations.VisibleForTesting
import org.jetbrains.plugins.gradle.util.GradleConstants
import java.util.function.Predicate
private const val ANDROID_LIBRARY_SUFFIX = "@aar"
fun LibraryOrderEntry.getArtifactCoordinates(): String? {
val libraryName = getLibraryName() ?: return null
val artifactCoordinates = libraryName.removePrefix("${GradleConstants.SYSTEM_ID.readableName}: ")
if (libraryName == artifactCoordinates) {
return null
}
return parseArtifactCoordinates(artifactCoordinates) { idCandidate ->
isArtifactId(idCandidate, this@getArtifactCoordinates)
}
}
@VisibleForTesting
fun parseArtifactCoordinates(artifactCoordinates: String, artifactIdChecker: Predicate<String>): String {
val rawCoordinates = artifactCoordinates.split(":").let {
when {
it.size == 4 && artifactIdChecker.test(it[1]) -> it[0] + ":" + it[1] + ":" + it[3]
it.size == 5 -> it[0] + ":" + it[1] + ":" + it[4]
else -> artifactCoordinates
}
}
return rawCoordinates.removeSuffix(ANDROID_LIBRARY_SUFFIX)
}
fun getLibraryUnifiedCoordinates(sourceArtifactNotation: String): UnifiedCoordinates? =
sourceArtifactNotation.replace(ANDROID_LIBRARY_SUFFIX, "")
.split(":")
.let { if (it.size < 3) null else UnifiedCoordinates(it[0], it[1], it[2]) }
private fun isArtifactId(artifactIdCandidate: String, libraryOrderEntry: LibraryOrderEntry): Boolean {
val rootFiles = libraryOrderEntry.getRootFiles(OrderRootType.CLASSES)
return rootFiles.size == 0 || rootFiles.any { file -> file.getName().startsWith(artifactIdCandidate) }
}
@@ -1,74 +0,0 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.gradle.service.sources
import junit.framework.AssertionFailedError
import org.jetbrains.plugins.gradle.DefaultExternalDependencyId
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.util.*
class ArtifactCoordinatesUtilTest {
@Test
fun `test artifact notation parsing`() {
val dependencyId = getRandomDependencyId()
val actual = parseArtifactCoordinates(dependencyId.presentableName) { true }
assertEquals("${dependencyId.group}:${dependencyId.name}:${dependencyId.version}", actual)
}
@Test
fun `test artifact notation parsing with classifier`() {
val dependencyId = getRandomDependencyId()
val classifier = getRandomString()
dependencyId.classifier = classifier
val actual = parseArtifactCoordinates(dependencyId.presentableName) { true }
assertEquals("${dependencyId.group}:${dependencyId.name}:${dependencyId.version}", actual)
}
@Test
fun `test artifact notation parsing with packaging`() {
val dependencyId = getRandomDependencyId()
val packaging = getRandomString()
dependencyId.packaging = packaging
val actual = parseArtifactCoordinates(dependencyId.presentableName) { true }
assertEquals("${dependencyId.group}:${dependencyId.name}:${dependencyId.version}", actual)
}
@Test
fun `test artifact notation without version`() {
val group = getRandomString()
val artifact = getRandomString()
val actual = parseArtifactCoordinates("$group:$artifact") {
throw AssertionFailedError("artifactIdChecker shouldn't be called")
}
assertEquals("$group:$artifact", actual)
}
@Test
fun `test aar artifact notation parsing`() {
val group = getRandomString()
val artifact = getRandomString()
val version = getRandomString()
val actual = parseArtifactCoordinates("$group:$artifact:$version@aar") {
throw AssertionFailedError("artifactIdChecker shouldn't be called")
}
assertEquals("$group:$artifact:$version", actual)
}
private fun getRandomString(): String {
return UUID.randomUUID().toString().substring(0, 12)
}
private fun getRandomDependencyId(): DefaultExternalDependencyId {
return DefaultExternalDependencyId(
getRandomString(),
getRandomString(),
getRandomString()
)
}
}