Skip to content

Commit 013adb5

Browse files
committed
Add .properties file with current library descriptor format version. Log warning if format has been updated
1 parent a585351 commit 013adb5

File tree

3 files changed

+44
-12
lines changed

3 files changed

+44
-12
lines changed

libraries/.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
formatVersion=1.0
1+
formatVersion=1

src/main/kotlin/org/jetbrains/kotlin/jupyter/config.kt

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package org.jetbrains.kotlin.jupyter
22

33
import com.beust.klaxon.JsonObject
44
import com.beust.klaxon.Parser
5+
import khttp.responses.Response
56
import kotlinx.coroutines.Deferred
67
import kotlinx.coroutines.GlobalScope
78
import kotlinx.coroutines.async
9+
import org.jetbrains.kotlin.konan.parseKonanVersion
810
import org.json.JSONObject
911
import org.slf4j.LoggerFactory
1012
import java.io.File
@@ -25,6 +27,7 @@ val GitHubBranchName = "remote_config"
2527
val GitHubApiPrefix = "https://$GitHubApiHost/repos/$GitHubRepoOwner/$GitHubRepoName"
2628

2729
val LibraryDescriptorExt = "json"
30+
val LibraryPropertiesFile = ".properties"
2831

2932
internal val log by lazy { LoggerFactory.getLogger("ikotlin") }
3033

@@ -48,7 +51,7 @@ data class KernelConfig(
4851

4952
val protocolVersion = "5.3"
5053

51-
val libraryDescriptorFormatVersion = "1.0"
54+
val libraryDescriptorFormatVersion = 1
5255

5356
data class TypeRenderer(val className: String, val displayCode: String?, val resultCode: String?)
5457

@@ -99,7 +102,7 @@ fun getLatestCommitToLibraries(sinceTimestamp: String?): Pair<String, String>? =
99102
if (sinceTimestamp != null)
100103
url += "&since=$sinceTimestamp"
101104
log.info("Checking for new commits to library descriptors at $url")
102-
val arr = khttp.get(url).jsonArray
105+
val arr = getHttp(url).jsonArray
103106
if (arr.length() == 0) {
104107
if (sinceTimestamp != null)
105108
getLatestCommitToLibraries(null)
@@ -115,6 +118,25 @@ fun getLatestCommitToLibraries(sinceTimestamp: String?): Pair<String, String>? =
115118
}
116119
}
117120

121+
fun getHttp(url: String): Response {
122+
val response = khttp.get(url)
123+
if (response.statusCode != 200)
124+
throw Exception("Http request failed. Url = $url. Response = $response")
125+
return response
126+
}
127+
128+
fun getLibraryDescriptorVersion(commitSha: String) =
129+
log.catchAll {
130+
val url = "$GitHubApiPrefix/contents/$LibrariesDir/$LibraryPropertiesFile?ref=$commitSha"
131+
log.info("Checking current library descriptor format version from $url")
132+
val response = getHttp(url)
133+
val downloadUrl = (response as JSONObject)["download_url"].toString()
134+
val downloadResult = getHttp(downloadUrl)
135+
val result = downloadResult.text.parseIniConfig()["formatVersion"]!!.toInt()
136+
log.info("Current library descriptor format version: $result")
137+
result
138+
}
139+
118140
/***
119141
* Downloads library descriptors from GitHub to local cache if new commits in `libraries` directory were detected
120142
*/
@@ -126,7 +148,7 @@ fun downloadNewLibraryDescriptors() {
126148
val footprintFilePath = Paths.get(LocalSettingsPath, LocalCacheDir, CachedLibrariesFootprintFile).toString()
127149
log.info("Reading commit info for which library descriptors were cached: '$footprintFilePath'")
128150
val footprintFile = File(footprintFilePath)
129-
val footprint = footprintFile.readIniConfig()
151+
val footprint = footprintFile.tryReadIniConfig()
130152
val timestampRegex = """\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z""".toRegex()
131153
val syncedCommitTimestamp = footprint?.get("timestamp")?.validOrNull { timestampRegex.matches(it) }
132154
val syncedCommitSha = footprint?.get("sha")
@@ -138,26 +160,33 @@ fun downloadNewLibraryDescriptors() {
138160
return
139161
}
140162

163+
// Download library descriptor version
164+
165+
val descriptorVersion = getLibraryDescriptorVersion(latestCommitSha) ?: return
166+
if (descriptorVersion != libraryDescriptorFormatVersion) {
167+
if (descriptorVersion < libraryDescriptorFormatVersion)
168+
log.error("Incorrect library descriptor version in GitHub repository: $descriptorVersion")
169+
else
170+
log.warn("Couldn't download new library descriptors from GitHub repository because their format was updated. Please, update kotlin jupyter kernel to the latest version")
171+
return
172+
}
173+
141174
// Download library descriptors
142175

143176
log.info("New commits to library descriptors were detected. Downloading library descriptors for commit $latestCommitSha")
144177

145178
val libraries = log.catchAll {
146179
val url = "$GitHubApiPrefix/contents/$LibrariesDir?ref=$latestCommitSha"
147180
log.info("Requesting the list of library descriptors at $url")
148-
val response = khttp.get(url)
149-
if (response.statusCode != 200)
150-
throw Exception("Failed to get GitHub contents for '$LibrariesDir' from $url. Response = $response")
181+
val response = getHttp(url)
151182

152183
response.jsonArray.mapNotNull {
153184
val o = it as JSONObject
154185
val filename = o["name"] as String
155186
if ("""[\w-]+.$LibraryDescriptorExt""".toRegex().matches(filename)) {
156187
val libUrl = o["download_url"].toString()
157188
log.info("Downloading '$filename' from $libUrl")
158-
val res = khttp.get(libUrl)
159-
if (res.statusCode != 200)
160-
throw Exception("Failed to download '$filename' from $libUrl. Response = $res")
189+
val res = getHttp(libUrl)
161190
val text = res.jsonObject.toString()
162191
filename to text
163192
} else null

src/main/kotlin/org/jetbrains/kotlin/jupyter/util.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,12 @@ fun <T, R> Deferred<T>.asyncLet(selector: suspend (T) -> R): Deferred<R> = this.
3939

4040
fun <T> Deferred<T>.awaitBlocking(): T = if (isCompleted) getCompleted() else runBlocking { await() }
4141

42-
fun File.readIniConfig() =
42+
fun String.parseIniConfig() =
43+
split("\n").map { it.split('=') }.filter { it.count() == 2 }.map { it[0] to it[1] }.toMap()
44+
45+
fun File.tryReadIniConfig() =
4346
existsOrNull()?.let {
44-
catchAll { it.readLines().map { it.split('=') }.filter { it.count() == 2 }.map { it[0] to it[1] }.toMap() }
47+
catchAll { it.readText().parseIniConfig() }
4548
}
4649

4750
fun readJson(path: String) =

0 commit comments

Comments
 (0)