Compare commits

..

1 Commits

Author SHA1 Message Date
931bb3244f CI 2023-12-20 13:25:40 +00:00
6 changed files with 38 additions and 107 deletions

View File

@@ -11,6 +11,3 @@ tab_width = 4
[{*.yaml,*.yml}] [{*.yaml,*.yml}]
indent_size = 2 indent_size = 2
[{*.kt,*.kts}]
ij_kotlin_packages_to_use_import_on_demand = org.junit.jupiter.api

View File

@@ -30,11 +30,11 @@ jobs:
run: | run: |
export VERSION="$(echo ${{ github.ref_name }} | cut -c2-)" export VERSION="$(echo ${{ github.ref_name }} | cut -c2-)"
echo "Parsed version: '$VERSION'" echo "Parsed version: '$VERSION'"
echo "filesystem_version=$VERSION" >> "$GITHUB_OUTPUT" echo "tinyvm_version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Publish to Gitea package repository - name: Publish to Gitea package repository
env: env:
FILESYSTEM_VERSION: ${{ steps.parse.outputs.filesystem_version }} TINYVM_VERSION: ${{ steps.parse.outputs.tinyvm_version }}
GITEA_USERNAME: ${{ github.repository_owner }} GITEA_USERNAME: ${{ github.repository_owner }}
GITEA_TOKEN: ${{ secrets.deploy_token }} GITEA_TOKEN: ${{ secrets.deploy_token }}
run: ./gradlew publishAllPublicationsToGiteaRepository run: ./gradlew publishAllPublicationsToGiteaRepository

View File

@@ -3,28 +3,6 @@
This is a small project to make a very basic filesystem library in Kotlin and was created using the instructions below This is a small project to make a very basic filesystem library in Kotlin and was created using the instructions below
as part of my application to the JetBrains internship project "TeamCity Kotlin Script build step extension library". as part of my application to the JetBrains internship project "TeamCity Kotlin Script build step extension library".
The package is (very creatively) named `filesystem`.
## Usage
### Gradle
```kotlin
repositories {
// other repositories
maven { url "https://git.koval.net/api/packages/cyclane/maven" }
}
dependencies {
// other dependencies
implementation("net.koval.teamcity-build-step-extension-test-task:filesystem:0.1.0")
}
```
### Documentation
Use autocompletion and hover menus in your IDE, or download the
[generated HTML documentation](https://git.koval.net/cyclane/teamcity-build-step-extension-test-task/releases/download/v0.1.0/filesystem-0.1.0-javadoc.zip)
from the [latest release](https://git.koval.net/cyclane/teamcity-build-step-extension-test-task/releases).
## Instructions ## Instructions
Create a library implementing four classes: Create a library implementing four classes:

View File

@@ -6,14 +6,9 @@ import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
class FSCreator { class FSCreator {
/** // Create entry, leaving existing folders' contents, but overwriting existing files.
* Create entry, leaving existing folders' contents, but overwriting existing files.
*/
@Throws(FileSystemException::class) @Throws(FileSystemException::class)
fun create( fun create(entryToCreate: FSEntry, destination: String) {
entryToCreate: FSEntry,
destination: String,
) {
val queue = ArrayDeque<Pair<FSEntry, Path>>() val queue = ArrayDeque<Pair<FSEntry, Path>>()
queue.add(entryToCreate to Path.of(destination)) queue.add(entryToCreate to Path.of(destination))
@@ -25,8 +20,7 @@ class FSCreator {
is FSFile -> Files.createFile(path) is FSFile -> Files.createFile(path)
is FSFolder -> Files.createDirectory(path) is FSFolder -> Files.createDirectory(path)
} }
} catch (_: FileAlreadyExistsException) { } catch (_: FileAlreadyExistsException) {} // Allow files/folders to already exist.
} // Allow files/folders to already exist.
when (entry) { when (entry) {
is FSFile -> Files.write(path, entry.content.toByteArray()) is FSFile -> Files.write(path, entry.content.toByteArray())
is FSFolder -> queue.addAll(entry.entries.map { it to path }) is FSFolder -> queue.addAll(entry.entries.map { it to path })

View File

@@ -1,9 +1,9 @@
package filesystem package filesystem
// Note sealed allows for simpler logic in FSCreator by guaranteeing FSFile and FSFolder are the only possible FSEntries // Note sealed allows for simpler logic in FSCreator by guaranteeing FSFile and FSFolder are the only possible FSEntries
// (as we expect), and it also implicitly makes the class abstract as required. // (as we expect), and it also makes the class abstract as required.
sealed class FSEntry(val name: String) sealed class FSEntry(val name: String)
class FSFile(name: String, val content: String) : FSEntry(name) class FSFile(name: String, val content: String): FSEntry(name)
class FSFolder(name: String, val entries: List<FSEntry>) : FSEntry(name) class FSFolder(name: String, val entries: List<FSEntry>): FSEntry(name)

View File

@@ -29,36 +29,19 @@ class FSCreatorTest {
fun `create entries`() { fun `create entries`() {
val readme = FSFile("README", "Hello World!") val readme = FSFile("README", "Hello World!")
val gomod = FSFile("go.mod", "module example.com/hello-world\n\ngo1.21.5") val gomod = FSFile("go.mod", "module example.com/hello-world\n\ngo1.21.5")
val maingo = val maingo = FSFile("main.go", "package main\n\nimport \"example.com/hello-world/utils\"\n\n" +
FSFile( "func main() {\n\tprintln(\"Hello World!\")\n}")
"main.go", val helloworldgo = FSFile("hello-world.go", "package utils\n\nfunc PrintHelloWorld() {\n" +
"package main\n\nimport \"example.com/hello-world/utils\"\n\n" + "\tprintln(\"Hello World!\")\n}")
"func main() {\n\tprintln(\"Hello World!\")\n}",
)
val helloworldgo =
FSFile(
"hello-world.go",
"package utils\n\nfunc PrintHelloWorld() {\n" +
"\tprintln(\"Hello World!\")\n}",
)
assertDoesNotThrow("should create entries") { assertDoesNotThrow("should create entries") {
creator.create( creator.create(FSFolder("folder", listOf(
FSFolder( readme,
"folder", gomod,
listOf( maingo,
readme, FSFolder("utils", listOf(
gomod, helloworldgo
maingo, ))
FSFolder( )), "_tmp")
"utils",
listOf(
helloworldgo,
),
),
),
),
"_tmp",
)
} }
// If objects don't exist, these functions will throw anyway, so don't explicitly check for existence. // If objects don't exist, these functions will throw anyway, so don't explicitly check for existence.
// Similarly, don't explicitly check if an object is a directory. // Similarly, don't explicitly check if an object is a directory.
@@ -71,46 +54,25 @@ class FSCreatorTest {
@Test @Test
fun `create existing entries`() { fun `create existing entries`() {
assertDoesNotThrow("creation one") { assertDoesNotThrow("creation one") {
creator.create( creator.create(FSFolder("folder", listOf(
FSFolder( FSFolder("sub-folder", listOf(
"folder", FSFile("hi", "hi")
listOf( )),
FSFolder( FSFolder("another-folder", listOf()),
"sub-folder", FSFile("1.txt", "One!"),
listOf( FSFile("2.txt", "Two!")
FSFile("hi", "hi"), )), "_tmp")
),
),
FSFolder("another-folder", listOf()),
FSFile("1.txt", "One!"),
FSFile("2.txt", "Two!"),
),
),
"_tmp",
)
} }
assertDoesNotThrow("creation two") { assertDoesNotThrow("creation two") {
creator.create( creator.create(FSFolder("folder", listOf(
FSFolder( FSFolder("another-folder", listOf(
"folder", FSFolder("secrets", listOf(
listOf( FSFile("secret", "P4ssW0rd")
FSFolder( ))
"another-folder", )),
listOf( FSFile("1.txt", "One is a good number"),
FSFolder( FSFile("3.txt", "Three!")
"secrets", )), "_tmp")
listOf(
FSFile("secret", "P4ssW0rd"),
),
),
),
),
FSFile("1.txt", "One is a good number"),
FSFile("3.txt", "Three!"),
),
),
"_tmp",
)
} }
assertEquals("hi", Files.readString(Path.of("_tmp/folder/sub-folder/hi"))) assertEquals("hi", Files.readString(Path.of("_tmp/folder/sub-folder/hi")))
assertEquals("P4ssW0rd", Files.readString(Path.of("_tmp/folder/another-folder/secrets/secret"))) assertEquals("P4ssW0rd", Files.readString(Path.of("_tmp/folder/another-folder/secrets/secret")))