initial commit

This commit is contained in:
moehreag 2024-06-13 23:22:04 +02:00
commit b4f5d8b797
9 changed files with 281 additions and 0 deletions

41
.gitignore vendored Normal file
View file

@ -0,0 +1,41 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### IntelliJ IDEA ###
.idea/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
.kotlin/
/.profileconfig.json

3
.idea/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

70
build.gradle.kts Normal file
View file

@ -0,0 +1,70 @@
import java.util.Date
plugins {
kotlin("jvm") version "2.0.0"
`java-gradle-plugin`
`maven-publish`
}
group = "dev.frogmc"
version = "0.0.1-alpha.1"
repositories {
mavenCentral()
}
dependencies {
implementation("com.google.guava:guava:33.2.1-jre")
testImplementation(kotlin("test"))
}
gradlePlugin {
plugins {
create("meta-update") {
id = "dev.frogmc.meta-update"
implementationClass = "dev.frogmc.meta_update.MetaUpdatePlugin"
}
}
}
tasks.jar {
manifest {
attributes("Implementation-Version" to version,
"Implementation-Date" to Date(),
"Implementation-Name" to project.name
)
}
}
tasks.test {
useJUnitPlatform()
}
kotlin {
jvmToolchain(21)
}
publishing {
publications {
}
repositories {
maven {
name = "FrogMCSnapshotsMaven"
url = uri("https://maven.frogmc.dev/snapshots")
credentials(PasswordCredentials::class)
authentication {
create<BasicAuthentication>("basic")
}
}
maven {
name = "FrogMCReleasesMaven"
url = uri("https://maven.frogmc.dev/releases")
credentials(PasswordCredentials::class)
authentication {
create<BasicAuthentication>("basic")
}
}
}
}

1
gradle.properties Normal file
View file

@ -0,0 +1 @@
kotlin.code.style=official

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,6 @@
#Sun May 12 17:35:40 BST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

5
settings.gradle.kts Normal file
View file

@ -0,0 +1,5 @@
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}
rootProject.name = "meta-update"

View file

@ -0,0 +1,10 @@
package dev.frogmc.meta_update
import org.gradle.api.Plugin
import org.gradle.api.Project
class MetaUpdatePlugin: Plugin<Project> {
override fun apply(target: Project) {
val task = target.tasks.register("updateMeta", MetaV1UpdateTask::class.java)
}
}

View file

@ -0,0 +1,145 @@
package dev.frogmc.meta_update
import com.google.common.hash.Hashing
import groovy.json.JsonOutput
import org.gradle.api.DefaultTask
import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
import java.net.URI
import java.net.URLEncoder
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse.BodyHandlers
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.time.ZoneOffset
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
@DisableCachingByDefault(because = "Not worth caching")
class MetaV1UpdateTask : DefaultTask() {
init {
dependsOn(project.tasks.getByName(JavaBasePlugin.BUILD_TASK_NAME))
}
private val timeFormat = DateTimeFormatter.ISO_LOCAL_DATE_TIME
private val client = HttpClient.newHttpClient()
@Suppress("DEPRECATION") // Because SHA-1 is deprecated i suppose for being "neither secure nor fast"
@TaskAction
fun upload() {
if (project.name != "frogloader") {
error("Cannot upload invalid project to FrogMC Meta!")
}
val version = project.version.toString()
val date = ZonedDateTime.of(ZonedDateTime.now().toLocalDateTime(), ZoneOffset.UTC).format(timeFormat)
val libraries = project.configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)
.resolvedConfiguration.resolvedArtifacts.map {
val module = it.moduleVersion.id
val file = it.file
val url = findUrl(it)
if (url.isEmpty()) {
error("Failed to resolve original url of ${module.group + ":" + module.name + ":" + module.version}!")
}
return@map MetaLibrary(
module.group + ":" + module.name + ":" + module.version + (if (it.classifier != null) ":" + it.classifier else ""),
url, Files.size(file.toPath()), Hashing.sha1().hashBytes(file.readBytes()).toString()
)
}.toMutableList()
val builtFile = project.tasks.getByName(JavaBasePlugin.BUILD_TASK_NAME).outputs.files.files.find { !it.name.endsWith("-dev.jar") && !it.name.endsWith("-sources.jar") && !it.name.endsWith("-javadoc.jar") }
libraries.add(MetaLibrary(project.name, getOwnUrl(), Files.size(builtFile!!.toPath()), Hashing.sha1().hashBytes(builtFile.readBytes()).toString()))
val json = JsonOutput.toJson(MetaData(version, date, libraries))
println("Data for upload: $json")
val key = project.properties.getOrDefault("FrogMCMetaKey", "") as String
if (key.isEmpty()) {
error("No Authentication Key provided!")
}
val post = HttpRequest.newBuilder(URI.create(UPLOAD_LOADER_URL)).POST(HttpRequest.BodyPublishers.ofString(json))
.header("Authorization", key)
.build()
val response = client.send(post, BodyHandlers.ofString())
if (response.statusCode() == 200) {
println("Uploaded information for version ${project.version} to FrogMC Meta!")
} else {
error(buildString {
append("Failed to upload information for version ")
append(project.version)
append(" to FrogMC Meta!")
append("\n")
append("Status: ${response.statusCode()}\n")
append("Response body: " + response.body() + "\n")
append("Headers: " + response.headers().map())
})
}
}
private fun findUrl(artifact: ResolvedArtifact): String {
val module = artifact.moduleVersion.id
val escapedVersion = URLEncoder.encode(module.version, StandardCharsets.UTF_8)
val escapedGroup = URLEncoder.encode(module.group, StandardCharsets.UTF_8).replace(".", "/")
val escapedName = URLEncoder.encode(module.name, StandardCharsets.UTF_8)
project.repositories.filterIsInstance<MavenArtifactRepository>().map { it.url }
.forEach {
val artifactUrl = "%s%s/%s/%s/%s-%s.jar".format(
it, escapedGroup, escapedName, escapedVersion, escapedName, escapedVersion
)
runCatching {
val response = client.send(
HttpRequest.newBuilder().uri(URI.create(artifactUrl)).GET().build(),
BodyHandlers.discarding()
)
if (response.statusCode() == 200) {
return artifactUrl
}
}
}
return ""
}
private fun getOwnUrl(): String {
val escapedVersion = URLEncoder.encode(project.version.toString(), StandardCharsets.UTF_8)
val escapedGroup = URLEncoder.encode(project.group.toString(), StandardCharsets.UTF_8).replace(".", "/")
val escapedName = URLEncoder.encode(project.name, StandardCharsets.UTF_8)
val url = "%s/%s/%s/%s-%s.jar".format(
escapedGroup, escapedName, escapedVersion, escapedName, escapedVersion
)
runCatching {
val response = client.send(
HttpRequest.newBuilder().uri(URI.create(MAVEN_URL_RELEASES+url)).GET().build(),
BodyHandlers.discarding()
)
if (response.statusCode() == 200) {
return MAVEN_URL_RELEASES+url
}
}
return MAVEN_URL_SNAPSHOTS+url
}
companion object {
private const val META_URL = "https://meta.frogmc.dev/v1/"
private const val UPLOAD_LOADER_URL = META_URL + "loader/versions/upload"
private const val MAVEN_URL = "https://maven.frogmc.dev/"
private const val MAVEN_URL_RELEASES = "https://maven.frogmc.dev/releases"
private const val MAVEN_URL_SNAPSHOTS = "https://maven.frogmc.dev/snapshots"
}
}
class MetaData(val version: String, val releaseDate: String, val libraries: List<MetaLibrary>)
class MetaLibrary(val name: String, val url: String, val size: Long, val sha1: String)