@@ -2,6 +2,7 @@ package org.jetbrains.kotlinx.jupyter.common
2
2
3
3
import kotlinx.serialization.json.JsonObject
4
4
import kotlinx.serialization.json.JsonPrimitive
5
+ import kotlinx.serialization.json.jsonPrimitive
5
6
import org.slf4j.Logger
6
7
import org.slf4j.LoggerFactory
7
8
import java.io.File
@@ -32,17 +33,29 @@ class LibraryDescriptorsManager private constructor(
32
33
val userLibrariesDir = userSettingsDir.resolve(userPath)
33
34
val userCacheDir = userSettingsDir.resolve(" cache" )
34
35
val localLibrariesDir = File (localPath)
36
+ val defaultBranch = " master"
37
+ val latestCommitOnDefaultBranch by lazy {
38
+ getLatestCommitToLibraries(defaultBranch)!! .first
39
+ }
40
+
35
41
fun homeLibrariesDir (homeDir : File ? = null) = (homeDir ? : File (" " )).resolve(homePath)
36
42
37
43
val localPropertiesFile = localLibrariesDir.resolve(PROPERTIES_FILE )
44
+ val commitHashFile by lazy {
45
+ localLibrariesDir.resolve(COMMIT_HASH_FILE ).also { file ->
46
+ if (! file.exists()) {
47
+ file.createDirsAndWrite()
48
+ }
49
+ }
50
+ }
38
51
39
52
fun descriptorFileName (name : String ) = " $name .$DESCRIPTOR_EXTENSION "
40
53
41
54
fun isLibraryDescriptor (file : File ): Boolean {
42
55
return file.isFile && file.name.endsWith(" .$DESCRIPTOR_EXTENSION " )
43
56
}
44
57
45
- fun getLatestCommitToLibraries (ref : String , sinceTimestamp : String? ): Pair <String , String >? {
58
+ fun getLatestCommitToLibraries (ref : String , sinceTimestamp : String? = null ): Pair <String , String >? {
46
59
return catchAll {
47
60
var url = " $apiPrefix /commits?path=$remotePath &sha=$ref "
48
61
if (sinceTimestamp != null ) {
@@ -69,18 +82,69 @@ class LibraryDescriptorsManager private constructor(
69
82
fun downloadLibraryDescriptor (ref : String , name : String ): String {
70
83
val url = " $apiPrefix /contents/$remotePath /$name .$DESCRIPTOR_EXTENSION ?ref=$ref "
71
84
logger.info(" Requesting library descriptor at $url " )
72
- val response = getHttp(url).jsonObject
73
-
74
- val downloadURL = (response[" download_url" ] as JsonPrimitive ).content
75
- val res = getHttp(downloadURL)
76
- return res.text
85
+ return downloadSingleFile(url)
77
86
}
78
87
79
88
fun checkRefExistence (ref : String ): Boolean {
80
89
val response = getHttp(" $apiPrefix /contents/$remotePath ?ref=$ref " )
81
90
return response.status.successful
82
91
}
83
92
93
+ fun checkIfRefUpToDate (remoteRef : String ): Boolean {
94
+ if (! commitHashFile.exists()) return false
95
+ val localRef = commitHashFile.readText()
96
+ return localRef == remoteRef
97
+ }
98
+
99
+ fun downloadLibraries (ref : String ) {
100
+ localLibrariesDir.mkdirs()
101
+
102
+ val url = " $apiPrefix /contents/$remotePath ?ref=$ref "
103
+ logger.info(" Requesting library descriptors at $url " )
104
+ val response = getHttp(url).jsonArray
105
+
106
+ for (item in response) {
107
+ item as JsonObject
108
+ if (item[" type" ]?.jsonPrimitive?.content != " file" ) continue
109
+
110
+ val fileName = item[" name" ]!! .jsonPrimitive.content
111
+ if (! fileName.endsWith(" .$DESCRIPTOR_EXTENSION " )) continue
112
+
113
+ val downloadUrl = item[" download_url" ]!! .jsonPrimitive.content
114
+ val descriptorResponse = getHttp(downloadUrl)
115
+
116
+ val descriptorText = descriptorResponse.text
117
+ val file = localLibrariesDir.resolve(fileName)
118
+ file.writeText(descriptorText)
119
+ }
120
+
121
+ saveLocalRef(ref)
122
+ }
123
+
124
+ fun downloadLatestPropertiesFile () {
125
+ val ref = latestCommitOnDefaultBranch
126
+ val url = " $apiPrefix /contents/$remotePath /$PROPERTIES_FILE ?ref=$ref "
127
+ logger.info(" Requesting $PROPERTIES_FILE file at $url " )
128
+ val text = downloadSingleFile(url)
129
+ localPropertiesFile.createDirsAndWrite(text)
130
+ }
131
+
132
+ private fun downloadSingleFile (contentsApiUrl : String ): String {
133
+ val response = getHttp(contentsApiUrl).jsonObject
134
+ val downloadUrl = response[" download_url" ]!! .jsonPrimitive.content
135
+ val res = getHttp(downloadUrl)
136
+ return res.text
137
+ }
138
+
139
+ private fun saveLocalRef (ref : String ) {
140
+ commitHashFile.createDirsAndWrite(ref)
141
+ }
142
+
143
+ private fun File.createDirsAndWrite (text : String = "") {
144
+ parentFile.mkdirs()
145
+ writeText(text)
146
+ }
147
+
84
148
private fun <T > catchAll (message : String = "", body : () -> T ): T ? = try {
85
149
body()
86
150
} catch (e: Throwable ) {
@@ -92,6 +156,7 @@ class LibraryDescriptorsManager private constructor(
92
156
private const val GITHUB_API_HOST = " api.github.com"
93
157
private const val DESCRIPTOR_EXTENSION = " json"
94
158
private const val PROPERTIES_FILE = " .properties"
159
+ private const val COMMIT_HASH_FILE = " commit_sha"
95
160
96
161
fun getInstance (
97
162
logger : Logger = LoggerFactory .getLogger(LibraryDescriptorsManager ::class.java),
0 commit comments