diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 000000000..cefbbd17f --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021 dzikoysk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + kotlin("jvm") version "1.5.21" + `maven-publish` +} + +allprojects { + group = "org.panda-lang" + version = "3.0.0-SNAPSHOT" + + apply(plugin = "org.jetbrains.kotlin.jvm") + apply(plugin = "maven-publish") + + publishing { + repositories { + maven { + credentials { + username = property("mavenUser") as String + password = property("mavenPassword") as String + } + name = "panda-repository" + url = uri("https://repo.panda-lang.org/releases") + } + } + } + + repositories { + mavenCentral() + maven { url = uri("https://repo.panda-lang.org/releases") } + maven { url = uri("https://s01.oss.sonatype.org/content/repositories/releases/") } + maven { url = uri("https://jitpack.io") } + } + + java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + withJavadocJar() + withSourcesJar() + } +} + + +/* +tasks.register("depsize") { + description = "Prints dependencies for \"default\" configuration" + doLast { listConfigurationDependencies(configurations["default"]) } +} + +tasks.register("depsize-all-configurations") { + description = "Prints dependencies for all available configurations" + doLast { + configurations + .filter { it.isCanBeResolved } + .forEach { listConfigurationDependencies(it) } + } +} + +fun listConfigurationDependencies(configuration: Configuration ) { + val formatStr = "%,10.2f" + val size = configuration.sumOf { it.length() / (1024.0 * 1024.0) } + val out = StringBuffer() + out.append("\nConfiguration name: \"${configuration.name}\"\n") + + if (size > 0) { + out.append("Total dependencies size:".padEnd(65)) + out.append("${String.format(formatStr, size)} Mb\n\n") + + configuration + .sortedBy { -it.length() } + .forEach { + out.append(it.name.padEnd(65)) + out.append("${String.format(formatStr, (it.length() / 1024.0))} kb\n") + } + } + else { + out.append("No dependencies found") + } + + println(out) +} + */ \ No newline at end of file diff --git a/reposilite-backend/reposilite-backend.gradle.kts b/reposilite-backend/build.gradle.kts similarity index 88% rename from reposilite-backend/reposilite-backend.gradle.kts rename to reposilite-backend/build.gradle.kts index 1aee049c1..a741d8bd7 100644 --- a/reposilite-backend/reposilite-backend.gradle.kts +++ b/reposilite-backend/build.gradle.kts @@ -14,39 +14,23 @@ * limitations under the License. */ -import org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL import org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED import org.gradle.api.tasks.testing.logging.TestLogEvent.PASSED import org.gradle.api.tasks.testing.logging.TestLogEvent.SKIPPED import org.gradle.api.tasks.testing.logging.TestLogEvent.STARTED plugins { - kotlin("jvm") version "1.5.21" - kotlin("kapt") version "1.5.21" - kotlin("plugin.serialization") version "1.5.20" + kotlin("kapt") + kotlin("plugin.serialization") version "1.5.21" application jacoco - `maven-publish` } -group = "org.panda-lang" -version = "3.0.0-SNAPSHOT" - application { mainClass.set("com.reposilite.ReposiliteLauncher") } publishing { - repositories { - maven { - credentials { - username = property("mavenUser") as String - password = property("mavenPassword") as String - } - name = "panda-repository" - url = uri("https://repo.panda-lang.org/releases") - } - } publications { create("library") { groupId = "org.panda-lang" @@ -56,19 +40,11 @@ publishing { } } -repositories { - mavenCentral() - maven { url = uri("https://repo.panda-lang.org/releases") } - maven { url = uri("https://s01.oss.sonatype.org/content/repositories/releases/") } - maven { url = uri("https://jitpack.io") } -} - dependencies { - implementation(kotlin("stdlib")) implementation(kotlin("reflect")) implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1") - val expressible = "1.0.7" + val expressible = "1.0.8" implementation("org.panda-lang:expressible:$expressible") implementation("org.panda-lang:expressible-kt:$expressible") testImplementation("org.panda-lang:expressible-junit:$expressible") @@ -148,11 +124,6 @@ dependencies { testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") } -java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 -} - kapt { arguments { arg("project", "${project.group}/${project.name}") @@ -176,8 +147,13 @@ tasks { useJUnitPlatform() testLogging { - events(STARTED, PASSED, FAILED, SKIPPED) - exceptionFormat = FULL + events( + STARTED, + PASSED, + FAILED, + SKIPPED + ) + exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL showExceptions = true showCauses = true showStackTraces = true diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/storage/infrastructure/FileSystemQuotaProviders.kt b/reposilite-backend/src/main/kotlin/com/reposilite/storage/infrastructure/FileSystemQuotaProviders.kt index 70b2d0374..e5c3912f5 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/storage/infrastructure/FileSystemQuotaProviders.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/storage/infrastructure/FileSystemQuotaProviders.kt @@ -23,7 +23,7 @@ internal class FixedQuota(rootDirectory: Path, private val maxSize: Long) : File override fun canHold(contentLength: Long): Result<*, ErrorResponse> = usage() .map { it + contentLength } - .filter({ it < maxSize }, { ErrorResponse(INSUFFICIENT_STORAGE, "Repository cannot hold the given file") }) + .filter({ it <= maxSize }, { ErrorResponse(INSUFFICIENT_STORAGE, "Repository cannot hold the given file") }) } diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/storage/infrastructure/FileSystemStorageProvider.kt b/reposilite-backend/src/main/kotlin/com/reposilite/storage/infrastructure/FileSystemStorageProvider.kt index bc143b289..2c9893c6b 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/storage/infrastructure/FileSystemStorageProvider.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/storage/infrastructure/FileSystemStorageProvider.kt @@ -84,9 +84,10 @@ internal abstract class FileSystemStorageProvider protected constructor( resolved(file) .let { file -> val size = measure.apply(input).toLong() + val spaceResponse = canHold(size) - if (canHold(size).isErr) { - return@catchIOException errorResponse(HttpCode.INSUFFICIENT_STORAGE, "Not enough storage space available") + if (spaceResponse.isErr) { + return@catchIOException errorResponse(HttpCode.INSUFFICIENT_STORAGE, "Not enough storage space available: " + spaceResponse.error.status) } if (file.parent != null && !Files.exists(file.parent)) { diff --git a/reposilite-backend/src/test/kotlin/com/reposilite/storage/StorageProviderSpec.kt b/reposilite-backend/src/test/kotlin/com/reposilite/storage/StorageProviderSpec.kt new file mode 100644 index 000000000..77ee6ad41 --- /dev/null +++ b/reposilite-backend/src/test/kotlin/com/reposilite/storage/StorageProviderSpec.kt @@ -0,0 +1,7 @@ +package com.reposilite.storage + +internal abstract class StorageProviderSpec { + + protected lateinit var storageProvider: StorageProvider + +} \ No newline at end of file diff --git a/reposilite-backend/src/test/kotlin/com/reposilite/storage/StorageProviderTest.kt b/reposilite-backend/src/test/kotlin/com/reposilite/storage/StorageProviderTest.kt index 9754bb6d4..70932066b 100644 --- a/reposilite-backend/src/test/kotlin/com/reposilite/storage/StorageProviderTest.kt +++ b/reposilite-backend/src/test/kotlin/com/reposilite/storage/StorageProviderTest.kt @@ -1,14 +1,17 @@ package com.reposilite.storage +import com.reposilite.maven.api.DocumentInfo +import com.reposilite.shared.FileType.FILE +import com.reposilite.shared.getSimpleName import com.reposilite.shared.toPath +import io.javalin.http.ContentType.APPLICATION_JAR import org.junit.jupiter.api.Assertions.assertArrayEquals +import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import panda.std.ResultAssertions.assertError import panda.std.ResultAssertions.assertOk -internal abstract class StorageProviderTest { - - protected lateinit var storageProvider: StorageProvider +internal abstract class StorageProviderTest : StorageProviderSpec() { @Test fun `should store and return valid resource` () { @@ -36,4 +39,22 @@ internal abstract class StorageProviderTest { assertArrayEquals(content, fetchResponse.get().readBytes()) } + @Test + fun `should return valid file details` () { + // given: a destination path to the resource and its content + val path = "/directory/file.jar".toPath() + val content = "content".toByteArray() + storageProvider.putFile(path, content) + + // when: file details are requested + val response = storageProvider.getFileDetails(path) + + // then: response should contain expected file details + val fileDetails = assertOk(response) as DocumentInfo + assertEquals(FILE, fileDetails.type) + assertEquals(path.getSimpleName(), fileDetails.name) + assertEquals(content.size.toLong(), fileDetails.contentLength) + assertEquals(APPLICATION_JAR, fileDetails.contentType) + } + } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 92d4b5b3b..e5e4c07b9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,15 +16,4 @@ rootProject.name = "reposilite-parent" -include( - "reposilite-backend" -) - -for (project in rootProject.children) { - project.apply { - projectDir = file(name) - buildFileName = "$name.gradle.kts" - require(projectDir.isDirectory) { "Project '${project.path} must have a $projectDir directory" } - require(buildFile.isFile) { "Project '${project.path} must have a $buildFile build script" } - } -} +include("reposilite-backend") \ No newline at end of file