diff --git a/.gitignore b/.gitignore index 010b909..7848be7 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ build # Ignore manual compilation results /de/jotoho/ /META-INF +/.idea diff --git a/app/build.gradle.kts b/app/build.gradle.kts deleted file mode 100644 index 061be2a..0000000 --- a/app/build.gradle.kts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * This generated file contains a sample Kotlin application project to get you started. - * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle - * User Manual available at https://docs.gradle.org/7.2/userguide/building_java_projects.html - */ - -plugins { - // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin. - id("org.jetbrains.kotlin.jvm") version "1.+" - - // Apply the application plugin to add support for building a CLI application in Java. - application -} - -repositories { - // Use Maven Central for resolving dependencies. - mavenCentral() -} - -dependencies { - // Align versions of all Kotlin components - implementation(platform("org.jetbrains.kotlin:kotlin-bom")) - - // Use the Kotlin JDK 8 standard library. - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") - - // This dependency is used by the application. - implementation("com.google.guava:guava:30.1.1-jre") - - // Use the Kotlin test library. - testImplementation("org.jetbrains.kotlin:kotlin-test") - - // Use the Kotlin JUnit integration. - testImplementation("org.jetbrains.kotlin:kotlin-test-junit") -} - -java { - sourceCompatibility = JavaVersion.VERSION_16 - targetCompatibility = JavaVersion.VERSION_16 -} - -tasks { - compileKotlin { - kotlinOptions { - jvmTarget = "16" - } - } -} - -application { - // Define the main class for the application. - mainClass.set("de.jotoho.waituntil.StartKt") -} diff --git a/app/src/main/kotlin/de/jotoho/waituntil/start.kt b/app/src/main/kotlin/de/jotoho/waituntil/start.kt deleted file mode 100644 index 32f4911..0000000 --- a/app/src/main/kotlin/de/jotoho/waituntil/start.kt +++ /dev/null @@ -1,101 +0,0 @@ -package de.jotoho.waituntil - -import java.util.Locale -import java.time.format.DateTimeFormatter -import java.time.format.FormatStyle -import java.util.TimeZone -import java.time.Instant -import java.time.LocalTime -import java.time.LocalDate -import java.time.ZonedDateTime -import java.time.temporal.ChronoUnit - -// This file contains the main function and other utility function necessary for interpreting the terminal arguments. -// See README.md and LICENSE.md for license information -// Author: Jonas Tobias Hopusch (@jotoho) - -val langGerman: String = Locale.GERMAN.getLanguage(); -val applicationOutputLanguage: String = if (Locale.getDefault().getLanguage().equals(Locale.GERMAN.getLanguage())) - Locale.GERMAN.getLanguage() - else Locale.ENGLISH.getLanguage(); - -fun waitUntilTimeStamp(timestamp: ZonedDateTime) { - Thread.sleep( - Math.max(Instant.now().until(timestamp, ChronoUnit.MILLIS), 0) - ); - - val formattedTimeStamp: String = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG) - .withZone(TimeZone.getDefault().toZoneId()) - .format(Instant.now()); - - when (applicationOutputLanguage) { - langGerman -> System.err.println("Erfolgreich bis $formattedTimeStamp gewartet!"); - else -> { - System.err.println("Successfully waited until $formattedTimeStamp"); - } - } -} - -fun calculateAndAnnounceTargetTime(userTimeInputRaw: String): ZonedDateTime { - val userTimeInputRelative = LocalTime.parse(userTimeInputRaw); - val userTimeInputAbsolute = ZonedDateTime.of(LocalDate.now(), userTimeInputRelative, TimeZone.getDefault().toZoneId()); - - val userTimeInputFinal = if (Instant.now().isBefore(userTimeInputAbsolute.toInstant())) userTimeInputAbsolute else userTimeInputAbsolute.plusDays(1); - - val formattedTimeStamp = userTimeInputFinal.format( - DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG) - ); - - when (applicationOutputLanguage) { - langGerman -> System.err.println("Dieses Program wird bis zum $formattedTimeStamp warten."); - else -> { - println("WaitUntil will suspend until $formattedTimeStamp"); - } - } - - return userTimeInputFinal; -} - -fun main(args: Array) { - val optionDictionary = mapOf(Pair("-h", "--help")); - - val options = HashSet(); - val words = HashSet(); - - for (arg in args) { - if (arg.startsWith("--")) { - options.add(arg.substring(startIndex=2)) - } - else if (arg.startsWith('-')) { - val translation = optionDictionary.get(arg); - if (translation != null) - options.add(translation.substring(startIndex=2)); - else - System.err.println("Short-hand '$arg' does not exist. Ignoring!"); - } - else - words.add(arg); - } - - if (options.contains("help")) { - when (applicationOutputLanguage) { - langGerman -> println("Hilfe kommt noch. (Nicht implementiert)"); - else -> { - println("Help is yet to come. (Not implemented)"); - } - } - } - else if (words.size == 1) { - val target = calculateAndAnnounceTargetTime(words.iterator().next()); - waitUntilTimeStamp(target); - } - else { - when (applicationOutputLanguage) { - langGerman -> System.err.println("FATAL: Es wurde exact ein nicht-flag Argument erwartet. (${words.size} erhalten)"); - else -> { - System.err.println("FATAL: Expected one non-flag argument. (Got ${words.size})"); - } - } - System.exit(1); - } -} diff --git a/app/src/test/kotlin/waituntil/AppTest.kt b/app/src/test/kotlin/waituntil/AppTest.kt deleted file mode 100644 index 73edc1c..0000000 --- a/app/src/test/kotlin/waituntil/AppTest.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * This Kotlin source file was generated by the Gradle 'init' task. - */ -package de.jotoho.waituntil - -import kotlin.test.Test -import kotlin.test.assertNotNull - -class AppTest { - @Test fun appHasAGreeting() { - val classUnderTest = App() - assertNotNull(classUnderTest.greeting, "app should have a greeting") - } -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..603c97b --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,49 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin. + kotlin("jvm") version "latest.release" + + // Apply the application plugin to add support for building a CLI application in Java. + application +} + +group = "de.jotoho" +version = "0.1.0" + +repositories { + // Use Maven Central for resolving dependencies. + mavenCentral() +} + +dependencies { + // Align versions of all Kotlin components + implementation(platform(kotlin("bom", "latest.release"))) + + // Use the Kotlin standard library. + implementation(kotlin("stdlib", "latest.release")) + + // Use the Kotlin test library. + testImplementation(kotlin("test", "latest.release")) + + // Use the Kotlin JUnit integration. + testImplementation(kotlin("test-junit", "latest.release")) +} + +java { + sourceCompatibility = JavaVersion.VERSION_16 + targetCompatibility = JavaVersion.VERSION_16 +} + +tasks.test { + useJUnitPlatform() +} + +tasks.withType { + kotlinOptions.jvmTarget = "16" +} + +application { + // Define the main class for the application. + mainClass.set("de.jotoho.waituntil.StartKt") +} diff --git a/compile.sh b/compile.sh index 94bbae6..5c8fa93 100755 --- a/compile.sh +++ b/compile.sh @@ -1,3 +1,5 @@ #!/bin/sh -kotlinc app/src/main/kotlin/de/jotoho/waituntil/start.kt -jvm-target 16 -include-runtime -d waituntil.jar +# shellcheck disable=SC2046 +# Word splitting in find results is intentional! +kotlinc $(find src/main -type f -iname '*.kt') -jvm-target 16 -include-runtime -d waituntil.jar diff --git a/gradle.properties b/gradle.properties index 6b1823d..43d3784 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,2 @@ org.gradle.daemon=false +kotlin.code.style=official diff --git a/settings.gradle.kts b/settings.gradle.kts index 9c984f8..599ab7a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,5 +7,4 @@ * in the user manual at https://docs.gradle.org/7.2/userguide/multi_project_builds.html */ -rootProject.name = "de.jotoho.waituntil" -include("app") +rootProject.name = "waituntil" diff --git a/src/main/kotlin/de/jotoho/waituntil/sleeping.kt b/src/main/kotlin/de/jotoho/waituntil/sleeping.kt new file mode 100644 index 0000000..ae031b7 --- /dev/null +++ b/src/main/kotlin/de/jotoho/waituntil/sleeping.kt @@ -0,0 +1,24 @@ +package de.jotoho.waituntil + +import java.time.Instant +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter +import java.time.format.FormatStyle +import java.time.temporal.ChronoUnit +import java.util.* + +fun waitUntilTimeStamp(timestamp: ZonedDateTime) { + Thread.sleep(Instant.now().until(timestamp, ChronoUnit.MILLIS).coerceAtLeast(0)) + + val formattedTimeStamp: String = + DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG) + .withZone(TimeZone.getDefault().toZoneId()) + .format(Instant.now()) + + when (applicationOutputLanguage) { + langGerman -> System.err.println("Erfolgreich bis $formattedTimeStamp gewartet!") + else -> { + System.err.println("Successfully waited until $formattedTimeStamp") + } + } +} diff --git a/src/main/kotlin/de/jotoho/waituntil/start.kt b/src/main/kotlin/de/jotoho/waituntil/start.kt new file mode 100644 index 0000000..7a4275c --- /dev/null +++ b/src/main/kotlin/de/jotoho/waituntil/start.kt @@ -0,0 +1,56 @@ +package de.jotoho.waituntil + +import java.util.* +import kotlin.system.exitProcess + +// This file contains the main function and other utility function necessary for interpreting the terminal arguments. +// See README.md and LICENSE.md for license information +// Author: Jonas Tobias Hopusch (@jotoho) + +val langGerman: String = Locale.GERMAN.language +val applicationOutputLanguage: String = if (Locale.getDefault().language.equals(Locale.GERMAN.language)) + Locale.GERMAN.language + else Locale.ENGLISH.language + +fun main(args: Array) { + val optionDictionary = mapOf(Pair("-h", "--help")) + + val options = HashSet() + val words = HashSet() + + for (arg in args) { + if (arg.startsWith("--")) { + options.add(arg.substring(startIndex=2)) + } + else if (arg.startsWith('-')) { + if (optionDictionary.containsKey(arg)) + options.add(optionDictionary[arg]!!.substring(startIndex=2)) + else + System.err.println("Short-hand '$arg' does not exist. Ignoring!") + } + else + words.add(arg) + } + + if (options.contains("help")) { + when (applicationOutputLanguage) { + langGerman -> println("Hilfe kommt noch. (Nicht implementiert)") + else -> { + println("Help is yet to come. (Not implemented)") + } + } + } + else if (words.size == 1) { + val target = calculateAndAnnounceTargetTime(words.iterator().next()) + waitUntilTimeStamp(target) + } + else { + when (applicationOutputLanguage) { + langGerman -> System.err.println("FATAL: Es wurde exact ein nicht-flag Argument erwartet. (${words.size} erhalten)") + else -> { + System.err.println("FATAL: Expected one non-flag argument. (Got ${words.size})") + } + } + exitProcess(1) + } +} diff --git a/src/main/kotlin/de/jotoho/waituntil/timecalc.kt b/src/main/kotlin/de/jotoho/waituntil/timecalc.kt new file mode 100644 index 0000000..4a52357 --- /dev/null +++ b/src/main/kotlin/de/jotoho/waituntil/timecalc.kt @@ -0,0 +1,41 @@ +package de.jotoho.waituntil + +import java.time.Instant +import java.time.LocalDate +import java.time.LocalTime +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter +import java.time.format.FormatStyle +import java.util.TimeZone + +fun calculateAndAnnounceTargetTime(userTimeInputRaw: String): ZonedDateTime { + val userTimeInputRelative = LocalTime.parse(userTimeInputRaw) + val userTimeInputAbsolute = + ZonedDateTime.of( + LocalDate.now(), + userTimeInputRelative, + TimeZone.getDefault().toZoneId() + ) + + val userTimeInputFinal = + if (Instant.now().isBefore(userTimeInputAbsolute.toInstant())) + userTimeInputAbsolute + else userTimeInputAbsolute.plusDays(1) + + val formattedTimeStamp = + userTimeInputFinal.format( + DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG) + ) + + when (applicationOutputLanguage) { + langGerman -> + System.err.println( + "Dieses Program wird bis zum $formattedTimeStamp warten." + ) + else -> { + println("WaitUntil will suspend until $formattedTimeStamp") + } + } + + return userTimeInputFinal +}