Compare commits

..

62 Commits

Author SHA1 Message Date
2004a7dd05 update changelog 2023-05-25 20:53:58 +06:00
7c4217bda6 migration onto new klock and fixes in android manifest 2023-05-25 20:53:10 +06:00
3d6fee7257 migrate onto 2.0.0 due to changes in klock 2023-05-25 20:50:48 +06:00
6cec25eca0 update kotlin version 2023-05-25 20:41:33 +06:00
a0972eaff9 start 1.1.0 2023-05-25 20:38:51 +06:00
cc75501b04 Merge pull request #49 from InsanusMokrassar/1.0.0
1.0.0
2023-04-25 00:28:01 +06:00
89e500ff33 Merge pull request #48 from InsanusMokrassar/renovate/configure
Configure Renovate
2023-04-25 00:15:38 +06:00
a61cd61602 update dependencies 2023-04-25 00:15:13 +06:00
renovate[bot]
5fdb2ea049 Add renovate.json 2023-04-24 18:11:35 +00:00
68ed562b19 start 1.0.0 2023-04-25 00:10:11 +06:00
87b5dfe1aa Update README.md 2023-04-03 16:18:18 +06:00
6a6bfe0552 Merge pull request #47 from InsanusMokrassar/0.10.0
0.10.0
2023-03-18 14:01:14 +06:00
ede47ae664 remove redundant FlowPrevies on flows API 2023-03-18 12:34:06 +06:00
890ab5b15d fill changelogs 2023-03-18 12:24:25 +06:00
5a1ed2f933 start 0.10.0 + rework of flows 2023-03-18 12:23:53 +06:00
7da67386cf Update gradle.properties 2023-03-16 20:00:52 +06:00
7027719fe5 Update gradle-wrapper.properties 2023-03-16 20:00:20 +06:00
a81c7c7c3f Merge pull request #46 from Tolsi/patch-1
typo
2023-03-16 18:20:18 +06:00
Sergey Tolmachev
e5658998d4 typo 2023-03-16 15:16:35 +03:00
6b3cb981ab Merge pull request #45 from InsanusMokrassar/0.9.0
0.9.0
2023-02-28 12:48:51 +06:00
f6518d4d25 add kotlin-js-store folder in gitignore 2023-02-28 12:25:23 +06:00
97a8f39826 update dependencies 2023-02-28 12:24:30 +06:00
469861f7e3 start 0.9.0 2023-02-28 12:23:12 +06:00
69305506ce Update README.md 2023-02-19 16:35:31 +06:00
63ea3f0f1a Merge pull request #44 from InsanusMokrassar/0.8.5
0.8.5
2022-12-15 08:38:54 +06:00
13a8bacb52 fix changelog 2022-12-15 08:37:54 +06:00
9c80e29e71 update autobuild script 2022-12-14 23:00:44 +06:00
cfd2de8fe9 update dependencies 2022-12-14 22:45:34 +06:00
e3490d432e fix in timezoned crontab scheduler 2022-12-14 22:44:27 +06:00
1c95636b71 start 0.8.5 2022-12-14 22:30:34 +06:00
b31a6ab86a Merge pull request #43 from InsanusMokrassar/0.8.4
0.8.4
2022-12-08 09:32:25 +06:00
c35a679827 update kotlin 2022-12-05 15:27:41 +06:00
06f56026db start 0.8.4 2022-12-05 15:26:31 +06:00
54be57d709 Merge pull request #42 from InsanusMokrassar/0.8.3
0.8.3
2022-11-15 10:04:46 +06:00
fae297e4a6 Update CHANGELOG.md 2022-11-14 10:11:46 +06:00
bd81298ac9 Update gradle.properties 2022-11-11 10:25:26 +06:00
cfac5fcd1c Merge pull request #41 from InsanusMokrassar/0.8.2
0.8.2
2022-10-02 22:37:13 +06:00
93d38f8945 Update CHANGELOG.md 2022-10-02 22:26:24 +06:00
97dcd77a8a Update gradle.properties 2022-10-02 22:22:04 +06:00
afa2521b5d Update gradle-wrapper.properties 2022-10-02 22:21:23 +06:00
37b0ec9fb7 start 0.8.2 2022-10-02 11:40:48 +06:00
d36888173a Merge pull request #40 from InsanusMokrassar/0.8.1
0.8.1
2022-09-13 00:58:24 +06:00
30011cd309 Update CHANGELOG.md 2022-09-11 14:18:46 +06:00
fd37a5ddc3 Update gradle.properties 2022-09-11 14:17:48 +06:00
3874f6a42c start 0.8.1 2022-09-11 14:16:52 +06:00
8a98ebd5f9 Merge pull request #39 from InsanusMokrassar/0.8.0
0.8.0
2022-08-06 10:01:18 +06:00
8d0c55129f Update CHANGELOG.md 2022-08-06 09:54:31 +06:00
54b06bf9e6 start 0.8.0 2022-08-06 09:50:59 +06:00
da436ab432 Merge pull request #38 from InsanusMokrassar/0.7.5
0.7.5
2022-07-22 17:09:31 +06:00
154d211514 change kdocs link 2022-07-22 17:09:00 +06:00
0b843ada4f update yarn.lock 2022-07-22 17:03:20 +06:00
25f204a488 update dependencies 2022-07-22 17:00:41 +06:00
2e4ccb9253 start 0.7.5 2022-07-22 16:59:07 +06:00
411a52b85e Update github_release.gradle 2022-07-02 18:38:03 +06:00
5a5bde6f20 Merge pull request #37 from InsanusMokrassar/0.7.4
0.7.4
2022-07-02 12:20:28 +06:00
8f9b84ecc7 Update CHANGELOG.md 2022-07-02 12:20:04 +06:00
62c5a0f98d Update gradle.properties 2022-07-01 23:01:29 +06:00
dfd1a5a909 Update gradle.properties 2022-07-01 23:00:34 +06:00
04390f0726 Update README.md 2022-06-15 15:18:41 +06:00
d0f02e37ce Merge pull request #36 from InsanusMokrassar/0.7.3
0.7.3
2022-06-15 14:48:10 +06:00
681043db5a Update NearDateTimeCalculator.kt 2022-06-15 14:46:12 +06:00
f63ed1a873 rename check infinity loop test class and fun 2022-06-15 14:43:28 +06:00
42 changed files with 302 additions and 2126 deletions

View File

@@ -8,18 +8,20 @@ jobs:
- uses: actions/setup-java@v1 - uses: actions/setup-java@v1
with: with:
java-version: 11 java-version: 11
- name: Fix android 32.0.0 dx
continue-on-error: true
run: cd /usr/local/lib/android/sdk/build-tools/32.0.0/ && cp d8 dx && cd lib && cp d8.jar dx.jar
- name: Update version - name: Update version
run: | run: |
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`" branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"
sed -i -e "s/^version=\([0-9\.]*\)/version=\1-branch_$branch-build${{ github.run_number }}/" gradle.properties sed -i -e "s/^version=\([0-9\.]*\)/version=\1-branch_$branch-build${{ github.run_number }}/" gradle.properties
- name: prebuild - name: prebuild
run: ./gradlew clean build run: ./gradlew clean build
- name: Publish to Gitea
continue-on-error: true
run: ./gradlew publishAllPublicationsToGiteaRepository
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
- name: Publish package - name: Publish package
continue-on-error: true continue-on-error: true
run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication -x signAndroidReleasePublication -x signAndroidDebugPublication -x signAndroidReleasePublication run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository
env: env:
GITHUBPACKAGES_USER: ${{ github.actor }} GITHUBPACKAGES_USER: ${{ github.actor }}
GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }} GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}

2
.gitignore vendored
View File

@@ -9,4 +9,6 @@ settings.xml
build/ build/
out/ out/
kotlin-js-store/
local.properties local.properties

View File

@@ -1,5 +1,81 @@
# Changelog # Changelog
## 2.0.0
* Versions
* `Kotlin`: `1.8.21`
* `Klock`: `4.0.1`
* Support of `mingwx64` platform
## 1.0.0
* Versions
* `Kotlin`: `1.8.20`
* `AndroidXWork`: `2.8.1`
## 0.10.0
* New extensions for `KronScheduler`:
* `asTzFlowWithoutDelays`/`asFlowWithoutDelays`
* `asTzFlowWithDelays`/`asFlowWithDelays`
* Old `KronScheduler.asFlow` and `KronScheduler.asTzFlow` temporarily marked as deprecated: after several versions their
behaviour will be changed to undelayed one
* All the flow extensions now use `cold` non-channel flows. Potentially it should increase performance and decrease memory usage
## 0.9.0
* Versions
* `Kotlin`: `1.8.10`
* `AndroidXWork`: `2.8.0`
## 0.8.5
* Project is now available in owner `Gitea`: https://git.inmo.dev/InsanusMokrassar/-/packages/maven/dev.inmo-krontab
* `KronSchedulerTz#next` with incoming `DateTime` now will use adjusted local time instead of unadjusted one
* `CronDateTimeSchedulerTz#next` with incoming `DateTime` will convert that parameter to internal offset directly
## 0.8.4
* Versions
* `Kotlin`: `1.7.22`
## 0.8.3
* Versions
* `Kotlin`: `1.7.21`
* `Klock`: `3.4.0`
## 0.8.2
**THIS VERSION HAS CHANGED COMPILE ANDROID SDK FROM 32 -> 33**
* Versions
* `Kotlin`: `1.7.20`
* `Klock`: `3.2.0`
## 0.8.1
* Versions
* `Klock`: `3.1.0`
## 0.8.0
**THIS VERSION HAS CHANGED MIN ANDROID SDK FROM 19 -> 21**
* Versions
* `Kotlin`: `1.7.10`
* `Klock`: `3.0.0`
## 0.7.5
* Versions
* `Coroutines`: `1.6.4`
## 0.7.4
* Versions
* `Coroutines`: `1.6.3`
## 0.7.3 ## 0.7.3
* Versions * Versions

View File

@@ -1,9 +1,17 @@
# krontab # krontab
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab)
[![Build Status](https://github.com/InsanusMokrassar/krontab/actions/workflows/publishing_packages.yml/badge.svg)](https://github.com/InsanusMokrassar/krontab/actions/workflows/publishing_packages.yml)
[![KDocs](https://raw.githubusercontent.com/InsanusMokrassar/badges/master/kdocs.svg)](https://krontab.inmo.dev/index.html) [![Telegram Chat](https://img.shields.io/badge/Telegram%20Chat-0288D1?style=for-the-badge&logo=telegram&logoColor=white)](https://inmodev_chat.t.me)
![JVM](https://img.shields.io/badge/JVM-red?style=for-the-badge&logo=openjdk&logoColor=white)
![Android](https://img.shields.io/badge/Android-green?style=for-the-badge&logo=android&logoColor=white)
![Js](https://img.shields.io/badge/JavaScript-323330?style=for-the-badge&logo=javascript&logoColor=F7DF1E)
![Linux x64](https://img.shields.io/badge/Linux%20x64-white?style=for-the-badge&logo=linux&logoColor=black)
[![KDocs](https://img.shields.io/badge/KDocs-323330?style=for-the-badge&logo=Kotlin&logoColor=7F52FF)](https://insanusmokrassar.github.io/krontab/)
[![Tutorials](https://img.shields.io/badge/Tutorials-0288D1?style=for-the-badge&logo=bookstack&logoColor=white)](https://bookstack.inmo.dev/books/krontab)
Library was created to give oppotunity to launch some things from time to time according to some schedule in Library was created to give oppotunity to launch some things from time to time according to some schedule in
runtime of applications. runtime of applications.
@@ -19,7 +27,7 @@ Anyway, to start some action from time to time you will need to use one of exten
```kotlin ```kotlin
val kronScheduler = /* creating of KronScheduler instance */; val kronScheduler = /* creating of KronScheduler instance */;
kronScheuler.doWhile { kronScheduler.doWhile {
// some action // some action
true // true - repeat on next time true // true - repeat on next time
} }

View File

@@ -10,7 +10,7 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.github.breadmoirai:github-release:$github_release_plugin_version" classpath "com.github.breadmoirai:github-release:$github_release_plugin_version"
classpath "com.getkeepsafe.dexcount:dexcount-gradle-plugin:$dexcount_version" classpath "com.getkeepsafe.dexcount:dexcount-gradle-plugin:$dexcount_version"
classpath 'com.android.tools.build:gradle:7.0.4' classpath "com.android.tools.build:gradle:$android_gradle_version"
} }
} }
@@ -57,6 +57,8 @@ kotlin {
android { android {
publishAllLibraryVariants() publishAllLibraryVariants()
} }
linuxX64()
mingwX64()
sourceSets { sourceSets {
@@ -79,6 +81,7 @@ kotlin {
dependencies { dependencies {
implementation kotlin('test-common') implementation kotlin('test-common')
implementation kotlin('test-annotations-common') implementation kotlin('test-annotations-common')
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlin_coroutines_version"
} }
} }
jvmTest { jvmTest {
@@ -102,8 +105,9 @@ kotlin {
apply plugin: 'com.getkeepsafe.dexcount' apply plugin: 'com.getkeepsafe.dexcount'
android { android {
compileSdkVersion "$android_compileSdkVersion".toInteger() compileSdk "$android_compileSdkVersion".toInteger()
buildToolsVersion "$android_buildToolsVersion" buildToolsVersion "$android_buildToolsVersion"
namespace "${group}.${project.name}"
defaultConfig { defaultConfig {
minSdkVersion "$android_minSdkVersion".toInteger() minSdkVersion "$android_minSdkVersion".toInteger()

View File

@@ -21,7 +21,7 @@ if (new File(projectDir, "secret.gradle").exists()) {
owner "InsanusMokrassar" owner "InsanusMokrassar"
repo "${rootProject.name}" repo "${rootProject.name}"
tagName "${project.version}" tagName "v${project.version}"
releaseName "${project.version}" releaseName "${project.version}"
targetCommitish "${project.version}" targetCommitish "${project.version}"

View File

@@ -1,3 +1,4 @@
org.gradle.jvmargs=-Xmx512m
kotlin.code.style=official kotlin.code.style=official
org.gradle.parallel=true org.gradle.parallel=true
kotlin.js.generate.externals=true kotlin.js.generate.externals=true
@@ -8,30 +9,31 @@ android.useAndroidX=true
android.enableJetifier=false android.enableJetifier=false
kotlin_version=1.6.21 kotlin_version=1.8.21
kotlin_coroutines_version=1.6.1 kotlin_coroutines_version=1.6.4
dokka_version=1.6.21 dokka_version=1.8.10
klockVersion=2.7.0 klockVersion=4.0.1
## Github reease ## Github reease
github_release_plugin_version=2.3.7 github_release_plugin_version=2.4.1
## Android ## Android
android_minSdkVersion=19 android_gradle_version=7.4.2
android_compileSdkVersion=32 android_minSdkVersion=21
android_buildToolsVersion=32.0.0 android_compileSdkVersion=33
dexcount_version=3.0.1 android_buildToolsVersion=33.0.2
dexcount_version=4.0.0
junit_version=4.12 junit_version=4.12
test_ext_junit_version=1.1.2 test_ext_junit_version=1.1.3
espresso_core=3.3.0 espresso_core=3.4.0
androidx_work_version=2.7.1 androidx_work_version=2.8.1
## Common ## Common
version=0.7.3 version=2.0.0
android_code_version=14 android_code_version=26

View File

@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/krontab/blob/master/LICENSE"}],"mavenConfig":{"name":"Krontab","description":"It is an analog of crontab util for Kotlin Coroutines","url":"https://github.com/InsanusMokrassar/krontab","vcsUrl":"https://github.com/InsanusMokrassar/krontab.git","includeGpgSigning":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/krontab"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}]}} {"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/krontab/blob/master/LICENSE"}],"mavenConfig":{"name":"Krontab","description":"It is an analog of crontab util for Kotlin Coroutines","url":"https://github.com/InsanusMokrassar/krontab","vcsUrl":"https://github.com/InsanusMokrassar/krontab.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/krontab"},{"name":"Gitea","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven","credsType":{"type":"dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository.CredentialsType.HttpHeaderCredentials","headerName":"Authorization","headerValueProperty":"GITEA_TOKEN"}},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}

View File

@@ -1,5 +1,4 @@
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
apply plugin: 'signing'
task javadocsJar(type: Jar) { task javadocsJar(type: Jar) {
classifier = 'javadoc' classifier = 'javadoc'
@@ -43,27 +42,58 @@ publishing {
maven { maven {
name = "GithubPackages" name = "GithubPackages"
url = uri("https://maven.pkg.github.com/InsanusMokrassar/krontab") url = uri("https://maven.pkg.github.com/InsanusMokrassar/krontab")
credentials { credentials {
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER') username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD') password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
} }
}
}
if (project.hasProperty('GITEA_TOKEN') || System.getenv('GITEA_TOKEN') != null) {
maven {
name = "Gitea"
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven")
credentials(HttpHeaderCredentials) {
name = "Authorization"
value = project.hasProperty('GITEA_TOKEN') ? project.property('GITEA_TOKEN') : System.getenv('GITEA_TOKEN')
}
authentication {
header(HttpHeaderAuthentication)
}
} }
} }
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) { if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
maven { maven {
name = "sonatype" name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/") url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials { credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER') username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD') password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
} }
} }
} }
} }
} }
} }
signing { if (project.hasProperty("signing.gnupg.keyName")) {
useGpgCmd() apply plugin: 'signing'
sign publishing.publications
signing {
useGpgCmd()
sign publishing.publications
}
task signAll {
tasks.withType(Sign).forEach {
dependsOn(it)
}
}
} }

6
renovate.json Normal file
View File

@@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]
}

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab package dev.inmo.krontab
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.DateTimeTz import korlibs.time.DateTimeTz
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlin.coroutines.coroutineContext import kotlin.coroutines.coroutineContext

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab package dev.inmo.krontab
import com.soywiz.klock.DateTime import korlibs.time.DateTime
/** /**
* This interface was created for abstraction of [next] operation. Currently, there is only * This interface was created for abstraction of [next] operation. Currently, there is only

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab package dev.inmo.krontab
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.DateTimeTz import korlibs.time.DateTimeTz
/** /**
* This interface extending [KronScheduler] to use [DateTimeTz] with taking into account offset of incoming time for * This interface extending [KronScheduler] to use [DateTimeTz] with taking into account offset of incoming time for
@@ -13,7 +13,7 @@ import com.soywiz.klock.DateTimeTz
interface KronSchedulerTz : KronScheduler { interface KronSchedulerTz : KronScheduler {
suspend fun next(relatively: DateTimeTz): DateTimeTz? suspend fun next(relatively: DateTimeTz): DateTimeTz?
override suspend fun next(relatively: DateTime): DateTime? = next(relatively.localUnadjusted) ?.local override suspend fun next(relatively: DateTime): DateTime? = next(relatively.local) ?.local
} }
suspend fun KronSchedulerTz.nextOrRelative(relatively: DateTimeTz): DateTimeTz = next(relatively) ?: getAnyNext( suspend fun KronSchedulerTz.nextOrRelative(relatively: DateTimeTz): DateTimeTz = next(relatively) ?: getAnyNext(
@@ -31,4 +31,4 @@ suspend fun KronScheduler.next(relatively: DateTimeTz) = if (this is KronSchedul
this.next(relatively.local) ?.toOffsetUnadjusted(relatively.offset) this.next(relatively.local) ?.toOffsetUnadjusted(relatively.offset)
} }
suspend fun KronScheduler.nextTimeZoned() = next(DateTime.now().local) suspend fun KronScheduler.nextTimeZoned() = next(DateTime.now().local)

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab package dev.inmo.krontab
import com.soywiz.klock.DateTime import korlibs.time.DateTime
class LambdaKronScheduler( class LambdaKronScheduler(
private val onNext: suspend (DateTime) -> DateTime? private val onNext: suspend (DateTime) -> DateTime?

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab package dev.inmo.krontab
import com.soywiz.klock.DateTimeTz import korlibs.time.DateTimeTz
class LambdaKronSchedulerTz( class LambdaKronSchedulerTz(
private val onNext: suspend (DateTimeTz) -> DateTimeTz? private val onNext: suspend (DateTimeTz) -> DateTimeTz?

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab package dev.inmo.krontab
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.krontab.builder.buildSchedule import dev.inmo.krontab.builder.buildSchedule
import dev.inmo.krontab.internal.* import dev.inmo.krontab.internal.*

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab package dev.inmo.krontab
import com.soywiz.klock.TimezoneOffset import korlibs.time.TimezoneOffset
import com.soywiz.klock.minutes import korlibs.time.minutes
import dev.inmo.krontab.internal.* import dev.inmo.krontab.internal.*
import dev.inmo.krontab.utils.Minutes import dev.inmo.krontab.utils.Minutes

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab.builder package dev.inmo.krontab.builder
import com.soywiz.klock.TimezoneOffset import korlibs.time.TimezoneOffset
import com.soywiz.klock.minutes import korlibs.time.minutes
import dev.inmo.krontab.KronScheduler import dev.inmo.krontab.KronScheduler
import dev.inmo.krontab.KronSchedulerTz import dev.inmo.krontab.KronSchedulerTz
import dev.inmo.krontab.internal.* import dev.inmo.krontab.internal.*

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab.collection package dev.inmo.krontab.collection
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.DateTimeTz import korlibs.time.DateTimeTz
import dev.inmo.krontab.* import dev.inmo.krontab.*
import dev.inmo.krontab.internal.* import dev.inmo.krontab.internal.*

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab.internal package dev.inmo.krontab.internal
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.TimezoneOffset import korlibs.time.TimezoneOffset
import dev.inmo.krontab.KronScheduler import dev.inmo.krontab.KronScheduler
/** /**

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab.internal package dev.inmo.krontab.internal
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.krontab.KronScheduler import dev.inmo.krontab.KronScheduler
/** /**

View File

@@ -1,7 +1,8 @@
package dev.inmo.krontab.internal package dev.inmo.krontab.internal
import com.soywiz.klock.DateTimeTz import korlibs.time.DateTime
import com.soywiz.klock.TimezoneOffset import korlibs.time.DateTimeTz
import korlibs.time.TimezoneOffset
import dev.inmo.krontab.KronScheduler import dev.inmo.krontab.KronScheduler
import dev.inmo.krontab.KronSchedulerTz import dev.inmo.krontab.KronSchedulerTz
@@ -18,6 +19,10 @@ internal data class CronDateTimeSchedulerTz internal constructor(
val dateTimeWithActualOffset = relatively.toOffset(offset).local val dateTimeWithActualOffset = relatively.toOffset(offset).local
return cronDateTime.toNearDateTime(dateTimeWithActualOffset) ?.toOffsetUnadjusted(offset) ?.toOffset(relatively.offset) return cronDateTime.toNearDateTime(dateTimeWithActualOffset) ?.toOffsetUnadjusted(offset) ?.toOffset(relatively.offset)
} }
override suspend fun next(relatively: DateTime): DateTime? {
return next(relatively.toOffset(offset)) ?.utc
}
} }
internal fun mergeCronDateTimeSchedulers( internal fun mergeCronDateTimeSchedulers(

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab.internal package dev.inmo.krontab.internal
import com.soywiz.klock.* import korlibs.time.*
import dev.inmo.krontab.utils.copy import dev.inmo.krontab.utils.copy
import kotlin.math.min import kotlin.math.min
@@ -101,7 +101,7 @@ internal fun NearDateTimeCalculatorDays(
times: Array<Byte> times: Array<Byte>
) = CommonNearDateTimeCalculator( ) = CommonNearDateTimeCalculator(
times, times,
{ (it.dayOfMonth - 1).toByte() }, { (it.dayOfMonth - 1).toByte() }, // index1, so, decrease
{ dateTime, newOne -> { dateTime, newOne ->
val dateTime = (if (newOne < dateTime.dayOfMonth) { val dateTime = (if (newOne < dateTime.dayOfMonth) {
dateTime.plus(1.months) dateTime.plus(1.months)

View File

@@ -1,7 +1,7 @@
package dev.inmo.krontab.utils package dev.inmo.krontab.utils
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.Month import korlibs.time.Month
import kotlin.math.min import kotlin.math.min
fun DateTime.copy( fun DateTime.copy(

View File

@@ -1,36 +1,91 @@
package dev.inmo.krontab.utils package dev.inmo.krontab.utils
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.DateTimeTz import korlibs.time.DateTimeTz
import dev.inmo.krontab.* import korlibs.time.milliseconds
import kotlinx.coroutines.FlowPreview import dev.inmo.krontab.KronScheduler
import dev.inmo.krontab.next
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
/** /**
* This [Flow] will trigger emitting each near time which will be returned from [this] [KronScheduler] with attention to * **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
* time zones
* *
* @see channelFlow * Will emit all the [KronScheduler.next] as soon as possible. In case [KronScheduler.next] return null, flow will
* @see KronSchedulerTz.doInfinityTz * be completed
*
* @param since Will be used as the first parameter for [KronScheduler.next] fun
*/ */
@FlowPreview fun KronScheduler.asTzFlowWithoutDelays(since: DateTimeTz = DateTime.nowLocal()): Flow<DateTimeTz> = flow {
fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = channelFlow { var previous = since
doInfinityTz { while (currentCoroutineContext().isActive) {
send(it) val next = next(previous) ?: break
emit(next)
previous = next + 1.milliseconds
} }
} }
/** /**
* This method is a map for [asTzFlow] and will works the same but return flow with [DateTime]s * **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
* *
* @see channelFlow * This [Flow] will use [asTzFlowWithoutDelays], but stop on each time until this time will happen
* @see KronScheduler.doInfinity
*/ */
@FlowPreview fun KronScheduler.asTzFlowWithDelays(): Flow<DateTimeTz> = asTzFlowWithoutDelays().onEach { futureHappenTime ->
fun KronScheduler.asFlow(): Flow<DateTime> = channelFlow { val now = DateTime.nowLocal()
doInfinity {
send(it) delay((futureHappenTime - now).millisecondsLong)
}
/**
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
*
* This [Flow] will use [asTzFlowWithoutDelays], but stop on each time until this time will happen
*/
@Deprecated(
"Behaviour will be changed. In some of near versions this flow will not delay executions",
ReplaceWith("this.asTzFlowWithDelays()", "dev.inmo.krontab.utils.asTzFlowWithDelays")
)
fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = asTzFlowWithDelays()
/**
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
*
* Will emit all the [KronScheduler.next] as soon as possible. In case [KronScheduler.next] return null, flow will
* be completed
*
* @param since Will be used as the first parameter for [KronScheduler.next] fun
*/
fun KronScheduler.asFlowWithoutDelays(since: DateTime = DateTime.now()): Flow<DateTime> = flow {
var previous = since
while (currentCoroutineContext().isActive) {
val next = next(previous) ?: break
emit(next)
previous = next + 1.milliseconds
} }
} }
/**
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
*
* This [Flow] will use [asFlowWithoutDelays], but stop on each time until this time will happen
*/
fun KronScheduler.asFlowWithDelays(): Flow<DateTime> = asFlowWithoutDelays().onEach { futureHappenTime ->
val now = DateTime.now()
delay((futureHappenTime - now).millisecondsLong)
}
/**
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
*
* This [Flow] will use [asFlowWithDelays], but stop on each time until this time will happen
*/
@Deprecated(
"Behaviour will be changed. In some of near versions this flow will not delay executions",
ReplaceWith("this.asFlowWithDelays()", "dev.inmo.krontab.utils.asFlowWithDelays")
)
fun KronScheduler.asFlow(): Flow<DateTime> = asFlowWithDelays()

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab.utils.flows package dev.inmo.krontab.utils.flows
import com.soywiz.klock.* import korlibs.time.*
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab.utils.flows package dev.inmo.krontab.utils.flows
import com.soywiz.klock.* import korlibs.time.*
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab.utils.flows package dev.inmo.krontab.utils.flows
import com.soywiz.klock.* import korlibs.time.*
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")

View File

@@ -1,6 +1,6 @@
package dev.inmo.krontab.utils.flows package dev.inmo.krontab.utils.flows
import com.soywiz.klock.* import korlibs.time.*
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")

View File

@@ -1,13 +1,14 @@
package dev.inmo.krontab.utils package dev.inmo.krontab.utils
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.days import korlibs.time.days
import dev.inmo.krontab.buildSchedule import dev.inmo.krontab.buildSchedule
import kotlinx.coroutines.test.runTest
import kotlin.test.* import kotlin.test.*
class InfinityLoopCheckTest { class CheckMonthsAndDaysCorrectWork {
@Test @Test
fun absenceOfInfinityLoopCheckTest() { fun checkMonthsAndDaysCorrectWork() {
val now = DateTime.now().startOfYear.startOfDay val now = DateTime.now().startOfYear.startOfDay
for (i in 0 until now.year.days) { for (i in 0 until now.year.days) {
val scheduleDateTime = (now + i.days) val scheduleDateTime = (now + i.days)

View File

@@ -1,6 +1,8 @@
package dev.inmo.krontab.utils package dev.inmo.krontab.utils
import kotlinx.coroutines.* import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
fun CoroutineScope.createFailJob(forTimeMillis: Long) = launch { fun CoroutineScope.createFailJob(forTimeMillis: Long) = launch {
delay(forTimeMillis) delay(forTimeMillis)

View File

@@ -1,8 +0,0 @@
package dev.inmo.krontab.utils
import kotlinx.coroutines.CoroutineScope
/**
* Workaround to use suspending functions in unit tests
*/
expect fun runTest(block: suspend (scope : CoroutineScope) -> Unit)

View File

@@ -2,8 +2,8 @@ package dev.inmo.krontab.utils
import dev.inmo.krontab.builder.buildSchedule import dev.inmo.krontab.builder.buildSchedule
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.test.runTest
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@@ -18,7 +18,7 @@ class SchedulerFlowTests {
} }
} }
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val mustBeCollected = 10 val mustBeCollected = 10
@@ -40,14 +40,14 @@ class SchedulerFlowTests {
} }
} }
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val testsCount = 10 val testsCount = 10
val failJob = it.createFailJob((testsCount * 2) * 1000L) val failJob = createFailJob((testsCount * 2) * 1000L)
val mustBeCollected = 10 val mustBeCollected = 10
val answers = (0 until testsCount).map { _ -> val answers = (0 until testsCount).map { _ ->
it.async { async {
var collected = 0 var collected = 0
flow.takeWhile { flow.takeWhile {
collected < mustBeCollected collected < mustBeCollected

View File

@@ -1,12 +1,11 @@
package dev.inmo.krontab.utils package dev.inmo.krontab.utils
import com.soywiz.klock.* import korlibs.time.*
import dev.inmo.krontab.KronSchedulerTz import dev.inmo.krontab.KronSchedulerTz
import dev.inmo.krontab.buildSchedule import dev.inmo.krontab.buildSchedule
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.flow.takeWhile
import kotlin.math.floor import kotlinx.coroutines.test.runTest
import kotlin.test.* import kotlin.test.*
@ExperimentalCoroutinesApi @ExperimentalCoroutinesApi
@@ -16,7 +15,7 @@ class StringParseTest {
fun testThatFlowIsCorrectlyWorkEverySecondBuiltOnString() { fun testThatFlowIsCorrectlyWorkEverySecondBuiltOnString() {
val kronScheduler = buildSchedule("*/1 * * * *") val kronScheduler = buildSchedule("*/1 * * * *")
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val mustBeCollected = 10 val mustBeCollected = 10
@@ -33,7 +32,7 @@ class StringParseTest {
fun testThatFlowIsCorrectlyWorkEverySecondWhenMillisIsHalfOfSecondBuiltOnString() { fun testThatFlowIsCorrectlyWorkEverySecondWhenMillisIsHalfOfSecondBuiltOnString() {
val kronScheduler = buildSchedule("*/1 * * * * 500ms") val kronScheduler = buildSchedule("*/1 * * * * 500ms")
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val mustBeCollected = 10 val mustBeCollected = 10
@@ -51,14 +50,14 @@ class StringParseTest {
fun testThatFlowIsCorrectlyWorkEverySecondWithMuchOfEmittersBuiltOnString() { fun testThatFlowIsCorrectlyWorkEverySecondWithMuchOfEmittersBuiltOnString() {
val kronScheduler = buildSchedule("*/1 * * * *") val kronScheduler = buildSchedule("*/1 * * * *")
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val testsCount = 10 val testsCount = 10
val failJob = it.createFailJob((testsCount * 2) * 1000L) val failJob = createFailJob((testsCount * 2) * 1000L)
val mustBeCollected = 10 val mustBeCollected = 10
val answers = (0 until testsCount).map { _ -> val answers = (0 until testsCount).map { _ ->
it.async { async {
var collected = 0 var collected = 0
flow.takeWhile { flow.takeWhile {
collected < mustBeCollected collected < mustBeCollected
@@ -81,7 +80,7 @@ class StringParseTest {
val rangesEnds = listOf(0 to 5, 30 to 35) val rangesEnds = listOf(0 to 5, 30 to 35)
val kronScheduler = buildSchedule("${rangesEnds.joinToString(",") { "${it.first}-${it.second}" }} * * * *") val kronScheduler = buildSchedule("${rangesEnds.joinToString(",") { "${it.first}-${it.second}" }} * * * *")
val flow = kronScheduler.asFlow() val flow = kronScheduler.asFlowWithoutDelays()
runTest { runTest {
val ranges = rangesEnds.map { it.first .. it.second }.flatten().distinct().toMutableList() val ranges = rangesEnds.map { it.first .. it.second }.flatten().distinct().toMutableList()
@@ -91,7 +90,10 @@ class StringParseTest {
flow.takeWhile { ranges.isNotEmpty() }.collect { flow.takeWhile { ranges.isNotEmpty() }.collect {
ranges.remove(it.seconds) ranges.remove(it.seconds)
collected++ collected++
assertTrue(collected <= expectedCollects) assertTrue(
collected <= expectedCollects,
"Expected value should be less than $expectedCollects, but was $collected. Ranges state: $ranges"
)
} }
assertEquals(expectedCollects, collected) assertEquals(expectedCollects, collected)
} }

View File

@@ -1,8 +1,9 @@
package dev.inmo.krontab.utils package dev.inmo.krontab.utils
import com.soywiz.klock.* import korlibs.time.*
import dev.inmo.krontab.builder.buildSchedule import dev.inmo.krontab.builder.buildSchedule
import dev.inmo.krontab.next import dev.inmo.krontab.next
import kotlinx.coroutines.test.runTest
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

View File

@@ -1,7 +1,8 @@
package dev.inmo.krontab.utils package dev.inmo.krontab.utils
import com.soywiz.klock.* import korlibs.time.*
import dev.inmo.krontab.builder.buildSchedule import dev.inmo.krontab.builder.buildSchedule
import kotlinx.coroutines.test.runTest
import kotlin.math.ceil import kotlin.math.ceil
import kotlin.test.* import kotlin.test.*

View File

@@ -1,5 +0,0 @@
package dev.inmo.krontab.utils
import kotlinx.coroutines.*
actual fun runTest(block: suspend (scope : CoroutineScope) -> Unit): dynamic = GlobalScope.promise { block(this) }

View File

@@ -1,9 +0,0 @@
package dev.inmo.krontab.utils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.runBlocking
/**
* Workaround to use suspending functions in unit tests
*/
actual fun runTest(block: suspend (scope: CoroutineScope) -> Unit) = runBlocking(block = block)

View File

@@ -1 +0,0 @@
<manifest package="dev.inmo.krontab"/>

View File

@@ -2,7 +2,7 @@ package dev.inmo.krontab
import android.content.Context import android.content.Context
import androidx.work.* import androidx.work.*
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
/** /**