Compare commits

...

4 Commits

Author SHA1 Message Date
ca221f1907 Fix publish CI
All checks were successful
Publish Workflow / Publish library (push) Successful in 8m54s
Test Workflow / Lint and test library (push) Successful in 17m35s
2023-12-20 17:01:16 +00:00
e83b313766 README update
All checks were successful
Publish Workflow / Publish library (push) Successful in 9m4s
Test Workflow / Lint and test library (push) Successful in 17m32s
2023-12-20 15:57:35 +00:00
1c5cafb04d Improve documentation
Some checks failed
Test Workflow / Lint and test library (push) Has been cancelled
Publish Workflow / Publish library (push) Has been cancelled
2023-12-20 15:42:31 +00:00
71d98e540b Steup CI (#1)
Some checks failed
Test Workflow / Lint and test library (push) Has been cancelled
Setup Github actions CI to test and publish the library.

Reviewed-on: #1
2023-12-20 15:34:40 +00:00
8 changed files with 223 additions and 39 deletions

View File

@@ -10,4 +10,7 @@ max_line_length = 120
tab_width = 4
[{*.yaml,*.yml}]
indent_size = 2
indent_size = 2
[{*.kt,*.kts}]
ij_kotlin_packages_to_use_import_on_demand = org.junit.jupiter.api

40
.github/workflows/publish.yaml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Publish Workflow
on:
push:
tags:
- v*
jobs:
publish:
name: Publish library
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v3
with:
distribution: adopt
java-version: 17
- name: Verify Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Run checks
run: ./gradlew check
- name: Parse parameters
id: parse
run: |
export VERSION="$(echo ${{ github.ref_name }} | cut -c2-)"
echo "Parsed version: '$VERSION'"
echo "filesystem_version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Publish to Gitea package repository
env:
FILESYSTEM_VERSION: ${{ steps.parse.outputs.filesystem_version }}
GITEA_USERNAME: ${{ github.repository_owner }}
GITEA_TOKEN: ${{ secrets.deploy_token }}
run: ./gradlew publishAllPublicationsToGiteaRepository

29
.github/workflows/test.yaml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: Test Workflow
on:
pull_request:
branches:
- main
push:
branches:
- main
jobs:
lint-and-test:
name: Lint and test library
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v3
with:
distribution: adopt
java-version: 17
- name: Verify Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Run checks
run: ./gradlew check

View File

@@ -3,6 +3,28 @@
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".
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
Create a library implementing four classes:

View File

@@ -1,9 +1,12 @@
plugins {
kotlin("jvm") version "1.9.21"
id("org.jmailen.kotlinter") version "4.1.0"
id("org.jetbrains.dokka") version "1.9.10"
`maven-publish`
}
group = "net.koval"
version = "1.0-SNAPSHOT"
group = "net.koval.teamcity-build-step-extension-test-task"
version = System.getenv("FILESYSTEM_VERSION")
repositories {
mavenCentral()
@@ -19,4 +22,47 @@ tasks.test {
kotlin {
jvmToolchain(11)
}
}
val dokkaHtml by tasks.getting(org.jetbrains.dokka.gradle.DokkaTask::class)
val javadocJar: TaskProvider<Jar> by tasks.registering(Jar::class) {
dependsOn(dokkaHtml)
archiveClassifier.set("javadoc")
from(dokkaHtml.outputDirectory)
}
publishing {
publications.register<MavenPublication>("gpr") {
artifactId = "filesystem"
from(components["java"])
artifact(javadocJar)
pom {
name.set("TeamCity Kotlin Script build step extension library - Test Task - test filesystem")
description.set("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\".")
url.set("https://git.koval.net/cyclane/teamcity-build-step-extension-test-task")
developers {
developer {
id.set("cyclane")
name.set("Gleb Koval")
email.set("gleb@koval.net")
}
}
scm {
url.set("https://git.koval.net/cyclane/teamcity-build-step-extension-test-task")
}
}
}
repositories {
maven {
name = "Gitea"
url = uri("https://git.koval.net/api/packages/cyclane/maven")
credentials {
username = System.getenv("GITEA_USERNAME")
password = System.getenv("GITEA_TOKEN")
}
}
}
}

View File

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

View File

@@ -1,9 +1,9 @@
package filesystem
// Note sealed allows for simpler logic in FSCreator by guaranteeing FSFile and FSFolder are the only possible FSEntries
// (as we expect), and it also makes the class abstract as required.
// (as we expect), and it also implicitly makes the class abstract as required.
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,19 +29,36 @@ class FSCreatorTest {
fun `create entries`() {
val readme = FSFile("README", "Hello World!")
val gomod = FSFile("go.mod", "module example.com/hello-world\n\ngo1.21.5")
val maingo = FSFile("main.go", "package main\n\nimport \"example.com/hello-world/utils\"\n\n" +
"func main() {\n\tprintln(\"Hello World!\")\n}")
val helloworldgo = FSFile("hello-world.go", "package utils\n\nfunc PrintHelloWorld() {\n" +
"\tprintln(\"Hello World!\")\n}")
val maingo =
FSFile(
"main.go",
"package main\n\nimport \"example.com/hello-world/utils\"\n\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") {
creator.create(FSFolder("folder", listOf(
readme,
gomod,
maingo,
FSFolder("utils", listOf(
helloworldgo
))
)), "_tmp")
creator.create(
FSFolder(
"folder",
listOf(
readme,
gomod,
maingo,
FSFolder(
"utils",
listOf(
helloworldgo,
),
),
),
),
"_tmp",
)
}
// 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.
@@ -54,25 +71,46 @@ class FSCreatorTest {
@Test
fun `create existing entries`() {
assertDoesNotThrow("creation one") {
creator.create(FSFolder("folder", listOf(
FSFolder("sub-folder", listOf(
FSFile("hi", "hi")
)),
FSFolder("another-folder", listOf()),
FSFile("1.txt", "One!"),
FSFile("2.txt", "Two!")
)), "_tmp")
creator.create(
FSFolder(
"folder",
listOf(
FSFolder(
"sub-folder",
listOf(
FSFile("hi", "hi"),
),
),
FSFolder("another-folder", listOf()),
FSFile("1.txt", "One!"),
FSFile("2.txt", "Two!"),
),
),
"_tmp",
)
}
assertDoesNotThrow("creation two") {
creator.create(FSFolder("folder", listOf(
FSFolder("another-folder", listOf(
FSFolder("secrets", listOf(
FSFile("secret", "P4ssW0rd")
))
)),
FSFile("1.txt", "One is a good number"),
FSFile("3.txt", "Three!")
)), "_tmp")
creator.create(
FSFolder(
"folder",
listOf(
FSFolder(
"another-folder",
listOf(
FSFolder(
"secrets",
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("P4ssW0rd", Files.readString(Path.of("_tmp/folder/another-folder/secrets/secret")))