Skip to content

Commit

Permalink
make logging more extensible and improve speed
Browse files Browse the repository at this point in the history
  • Loading branch information
PranavPurwar committed Mar 25, 2024
1 parent 8689968 commit e63373e
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 98 deletions.
1 change: 0 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@
*
*/

import org.jetbrains.kotlin.gradle.dsl.KotlinCompile

plugins {
id("org.jetbrains.kotlin.jvm") version "1.8.21"
id("java-library")
id("maven-publish")
application
}

repositories {
Expand Down Expand Up @@ -42,6 +41,10 @@ publishing {
}
}

application {
mainClass.set("org.cosmic.ide.dependency.resolver.MainKt")
}

dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3")
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import kotlin.time.measureTime

@OptIn(ExperimentalTime::class)
suspend fun main() {
val artifact = getArtifact("com.github.anonymous-ME", "OTPView", "0.1.0")
val artifact = getArtifact("com.google.android.material", "material", "1.12.0-beta01")
val dir = File("test")
dir.deleteRecursively()
dir.mkdir()
Expand All @@ -15,4 +15,4 @@ suspend fun main() {
artifact?.downloadArtifact(dir)
}
println("Total time: $time")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
*/

package org.cosmic.ide.dependency.resolver.api

import org.cosmic.ide.dependency.resolver.logger
import org.cosmic.ide.dependency.resolver.eventReciever
import org.cosmic.ide.dependency.resolver.parallelForEach
import org.cosmic.ide.dependency.resolver.resolvePOM
import java.io.File
import java.io.InputStream
import java.net.SocketException
import java.net.URL
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedQueue
import javax.xml.parsers.DocumentBuilderFactory

Expand All @@ -26,29 +26,13 @@ data class Artifact(
var repository: Repository? = null,
var extension: String = "jar"
) {
fun downloadTo(output: File) {
if (repository == null) {
throw IllegalStateException("Repository is not declared.")
}
output.createNewFile()
val dependencyUrl =
"${ repository!!.getURL() }/${ groupId.replace(".", "/") }/$artifactId/$version/$artifactId-$version" + "." + if (extension == "bundle") "jar" else extension
logger.info("Downloading $dependencyUrl")
try {
val stream = URL(dependencyUrl).openConnection().apply { connectTimeout = 2000; readTimeout = 5000 }.inputStream
output.outputStream().use { stream.copyTo(it) }
} catch (e: SocketException) {
downloadTo(output)
}
}

suspend fun downloadArtifact(output: File) {
output.mkdirs()
val artifacts = resolve()
artifacts.add(this)

val latestDeps =
ConcurrentLinkedQueue(artifacts.groupBy { it.groupId to it.artifactId }.values.map { artifact -> artifact.maxBy { it.version } })
ConcurrentLinkedQueue(artifacts.groupBy { it.groupId to it.artifactId }.values.map { artifact -> artifact.maxByOrNull { it.version } }.filterNotNull())

latestDeps.parallelForEach { art ->
val pom = art.getPOM()
Expand All @@ -60,26 +44,26 @@ data class Artifact(
if (packaging != null) art.extension = packaging.textContent
}
if (art.version.isNotEmpty() && art.repository != null) {
art.downloadTo(File(output, "${ art.artifactId }-${ art.version }" + "." + extension))
art.downloadTo(File(output, "${art.artifactId}-${art.version}.$extension"))
}
}
}

suspend fun resolve(resolved: ConcurrentLinkedQueue<Artifact> = ConcurrentLinkedQueue()): ConcurrentLinkedQueue<Artifact> {
suspend fun resolve(resolved: MutableSet<Artifact> = ConcurrentHashMap.newKeySet()): ConcurrentLinkedQueue<Artifact> {
val pom = getPOM() ?: return ConcurrentLinkedQueue()
val deps = ConcurrentLinkedQueue(pom.resolvePOM(resolved))
val deps = ConcurrentLinkedQueue(pom.resolvePOM(ConcurrentLinkedQueue(resolved)))
val artifacts = ConcurrentLinkedQueue<Artifact>()
deps.parallelForEach { dep ->
logger.fine("Resolving $dep from $this")
eventReciever.onResolving(this, dep)
if (dep.version.isBlank()) {
logger.info("Fetching latest version of ${dep.artifactId}")
eventReciever.onFetchingLatestVersion(dep)
val factory = DocumentBuilderFactory.newInstance()
val builder = factory.newDocumentBuilder()
val doc = builder.parse(dep.getMavenMetadata().byteInputStream())
val v = doc.getElementsByTagName("release").item(0)
if (v != null) {
dep.version = v.textContent
logger.info("Latest version of ${dep.groupId}:${dep.artifactId} is ${v.textContent}")
eventReciever.onFetchedLatestVersion(dep, dep.version)
}
}
artifacts.add(dep)
Expand All @@ -88,26 +72,44 @@ data class Artifact(
}
resolved.add(dep)
val depArtifacts = dep.resolve(resolved)
logger.info("Resolved $dep")
eventReciever.onResolutionComplete(dep)
resolved.addAll(depArtifacts)
artifacts.addAll(depArtifacts)
}
return artifacts
}

fun downloadTo(output: File) {
if (repository == null) {
throw IllegalStateException("Repository is not declared.")
}
output.createNewFile()
val dependencyUrl =
"${repository!!.getURL()}/${groupId.replace(".", "/")}/$artifactId/$version/$artifactId-$version.$extension"
eventReciever.onDownloadStart(this)
try {
val stream = URL(dependencyUrl).openConnection().apply { connectTimeout = 5000; readTimeout = 2000 }.inputStream
output.outputStream().use { stream.copyTo(it) }
eventReciever.onDownloadEnd(this)
} catch (e: SocketException) {
downloadTo(output)
} catch (e: Exception) {
eventReciever.onDownloadError(this, e)
}
}

fun getMavenMetadata(): String {
if (repository == null) {
return ""
}
val dependencyUrl =
"${repository?.getURL()}/${groupId.replace(".", "/")}/${artifactId}/maven-metadata.xml"
return URL(dependencyUrl).openConnection().apply { connectTimeout = 2000; readTimeout = 5000 }.inputStream.bufferedReader().readText()
"${repository?.getURL()}/${groupId.replace(".", "/")}/$artifactId/maven-metadata.xml"
return URL(dependencyUrl).openConnection().apply { connectTimeout = 5000; readTimeout = 2000 }.inputStream.bufferedReader().readText()
}


fun getPOM(): InputStream? {
val pomUrl =
"${ repository!!.getURL() }/${ groupId.replace(".", "/") }/$artifactId/$version/$artifactId-$version.pom"
"${repository!!.getURL()}/${groupId.replace(".", "/")}/$artifactId/$version/$artifactId-$version.pom"
if (version.isNotEmpty()) {
return try {
URL(pomUrl).openConnection()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.cosmic.ide.dependency.resolver.api

import java.util.logging.Logger

open class EventReciever {

val logger: Logger = Logger.getLogger("DependencyResolver")

open fun onArtifactFound(artifact: Artifact) {
logger.info("Found ${artifact.groupId}:${artifact.artifactId}:${artifact.version} in ${artifact.repository?.getName()}")
}

open fun onArtifactNotFound(artifact: Artifact) {
logger.info("No repository contains ${artifact.artifactId}:${artifact.version}")
}

open fun onFetchingLatestVersion(artifact: Artifact) {
logger.info("Fetching latest version of ${artifact.artifactId}")
}

open fun onFetchedLatestVersion(artifact: Artifact, version: String) {
logger.info("Fetched latest version of ${artifact.artifactId}: $version")
}

open fun onResolving(artifact: Artifact, dependency: Artifact) {
logger.info("Resolving $dependency from $artifact")
}

open fun onResolutionComplete(artifact: Artifact) {
logger.info("Resolution complete for ${artifact.artifactId}")
}

open fun onSkippingResolution(artifact: Artifact) {
logger.info("Skipping resolution of $artifact as it is already resolved")
}

open fun onVersionNotFound(artifact: Artifact) {
logger.info("Version not found for ${artifact.artifactId}")
}

open fun onDependenciesNotFound(artifact: Artifact) {
logger.info("No dependencies found for ${artifact.artifactId}")
}

open fun onInvalidScope(artifact: Artifact, scope: String) {
logger.info("Invalid scope $scope for ${artifact.artifactId}")
}

open fun onInvalidPOM(artifact: Artifact) {
logger.info("Invalid POM for ${artifact.artifactId}")
}

open fun onDownloadStart(artifact: Artifact) {
logger.info("Starting download of ${artifact.artifactId}:${artifact.version}")
}

open fun onDownloadEnd(artifact: Artifact) {
logger.info("Download complete for ${artifact.artifactId}:${artifact.version}")
}

open fun onDownloadError(artifact: Artifact, error: Throwable) {
logger.severe("Error downloading ${artifact.artifactId}:${artifact.version}: ${error.message}")
}
}
Loading

0 comments on commit e63373e

Please sign in to comment.