|
1 | 1 | package shop.itbug.flutterx.services |
2 | 2 |
|
3 | | -import com.intellij.notification.NotificationGroup |
4 | | -import com.intellij.notification.NotificationGroupManager |
5 | | -import com.intellij.notification.NotificationType |
6 | | -import com.intellij.openapi.Disposable |
7 | | -import com.intellij.openapi.application.ApplicationManager |
8 | | -import com.intellij.openapi.application.EDT |
9 | | -import com.intellij.openapi.application.runReadAction |
10 | | -import com.intellij.openapi.components.Service |
11 | | -import com.intellij.openapi.components.service |
12 | | -import com.intellij.openapi.project.Project |
13 | | -import com.intellij.openapi.project.guessProjectDir |
14 | | -import com.intellij.openapi.util.Computable |
15 | | -import com.intellij.psi.PsiFile |
16 | | -import com.intellij.psi.PsiManager |
17 | | -import com.intellij.psi.util.PsiTreeUtil |
18 | | -import com.intellij.util.messages.Topic |
19 | | -import kotlinx.coroutines.* |
20 | | -import org.jetbrains.yaml.YAMLUtil |
21 | | -import org.jetbrains.yaml.psi.YAMLFile |
22 | | -import org.jetbrains.yaml.psi.impl.YAMLBlockMappingImpl |
23 | 3 | import org.jetbrains.yaml.psi.impl.YAMLKeyValueImpl |
24 | 4 | import org.jetbrains.yaml.psi.impl.YAMLPlainTextImpl |
25 | | -import shop.itbug.flutterx.i18n.PluginBundle |
26 | | -import shop.itbug.flutterx.model.PubVersionDataModel |
27 | 5 | import shop.itbug.flutterx.util.DartPluginVersionName |
28 | | -import shop.itbug.flutterx.util.MyFileUtil |
29 | | -import shop.itbug.flutterx.util.YamlExtends |
30 | 6 |
|
31 | 7 |
|
32 | | -/** |
33 | | - * 包类型 |
34 | | - */ |
35 | | -enum class MyPackageGroup(val baseName: String) { |
36 | | - Dependencies("dependencies"), DevDependencies("dev_dependencies"), DependencyOverrides("dependency_overrides"); |
37 | | - |
38 | | - override fun toString(): String { |
39 | | - return baseName |
40 | | - } |
41 | | -} |
42 | | - |
43 | | - |
44 | | -data class PubPackage( |
45 | | - val first: MyDartPackage, |
46 | | - val second: PubVersionDataModel?, |
47 | | -) { |
48 | | - |
49 | | - override fun toString(): String { |
50 | | - return first.packageName |
51 | | - } |
52 | | - |
53 | | -} |
54 | 8 |
|
55 | 9 | data class MyDartPackage( |
56 | 10 | var packageName: String, |
57 | 11 | val element: YAMLKeyValueImpl, |
58 | 12 | val detail: DartPluginVersionName, |
59 | 13 | val versionElement: YAMLPlainTextImpl, |
60 | 14 | val error: String? = null, |
61 | | - val group: MyPackageGroup = MyPackageGroup.Dependencies |
62 | | -) { |
63 | | - /** |
64 | | - * 通过 api来向 pub加载插件的数据 |
65 | | - */ |
66 | | - fun getDetailApi(): PubPackage { |
67 | | - try { |
68 | | - val r = PubService.callPluginDetails(packageName) |
69 | | - return PubPackage(this, r) |
70 | | - } catch (e: Exception) { |
71 | | - return PubPackage(this.copy(error = e.localizedMessage), null) |
72 | | - } |
73 | | - } |
74 | | - |
75 | | - |
76 | | -} |
77 | | - |
78 | | -typealias DartCheckTaskComplete = () -> Unit |
79 | | - |
80 | | -data class DartPackageTaskParam( |
81 | | - val showNotification: Boolean = true, val complete: DartCheckTaskComplete? = null |
82 | 15 | ) |
83 | 16 |
|
84 | | -/** |
85 | | - * 项目包检测的服务类 |
86 | | - */ |
87 | | -@Service(Service.Level.PROJECT) |
88 | | -@Deprecated("不建议使用了这个") |
89 | | -class DartPackageCheckService(val project: Project) : Disposable { |
90 | | - private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default) |
91 | | - private var pubspecFile: YAMLFile? = null |
92 | | - var details: MutableList<PubPackage> = mutableListOf()///从服务器获取的数据 |
93 | | - var projectName: String = "Flutter App" |
94 | | - |
95 | | - |
96 | | - /** |
97 | | - * 读取项目的包文件,pubspec.yaml |
98 | | - */ |
99 | | - private fun getPubspecFile(): YAMLFile? { |
100 | | - if (pubspecFile != null) { |
101 | | - return pubspecFile |
102 | | - } |
103 | | - val projectDir = project.guessProjectDir() ?: return null |
104 | | - val pubspecFile = projectDir.findChild("pubspec.yaml") ?: return null |
105 | | - val file = ApplicationManager.getApplication().runReadAction(Computable<PsiFile?> { |
106 | | - PsiManager.getInstance(project).findFile(pubspecFile) |
107 | | - }) as YAMLFile |
108 | | - this.pubspecFile = file |
109 | | - val nameElement = runReadAction { YAMLUtil.getQualifiedKeyInFile(file, "name") } |
110 | | - if (nameElement != null) { |
111 | | - this.projectName = nameElement.valueText |
112 | | - } |
113 | | - return file |
114 | | - } |
115 | | - |
116 | | - /** |
117 | | - * 解析插件列表,不要在这里执行耗时的操作 |
118 | | - */ |
119 | | - fun getPackageInfos(): List<MyDartPackage> { |
120 | | - val pubspecFile = getPubspecFile() ?: return emptyList() |
121 | | - val r = runBlocking { |
122 | | - MyPackageGroup.entries.map { |
123 | | - async { |
124 | | - collectDependencies(it, pubspecFile) |
125 | | - } |
126 | | - }.awaitAll() |
127 | | - } |
128 | | - return r.flatten() |
129 | | - } |
130 | | - |
131 | | - |
132 | | - /** |
133 | | - * 收集包并分组 |
134 | | - */ |
135 | | - private fun collectDependencies(group: MyPackageGroup, file: YAMLFile): List<MyDartPackage> { |
136 | | - val deps = runReadAction { YAMLUtil.getQualifiedKeyInFile(file, group.baseName) } ?: return emptyList() |
137 | | - val block = deps.value as? YAMLBlockMappingImpl ?: return emptyList() |
138 | | - val packageElements = runReadAction { PsiTreeUtil.findChildrenOfType(block, YAMLKeyValueImpl::class.java) } |
139 | | - val r = runBlocking { |
140 | | - packageElements.map { |
141 | | - async(Dispatchers.EDT) { |
142 | | - YamlExtends(it).getMyDartPackageModel()?.copy( |
143 | | - ) |
144 | | - } |
145 | | - }.awaitAll() |
146 | | - } |
147 | | - return r.filterNotNull() |
148 | | - } |
149 | | - |
150 | | - /** |
151 | | - * 开始检测包,然后远程检测包的新版本信息 |
152 | | - */ |
153 | | - fun start() { |
154 | | - val list = getPackageInfos() |
155 | | - val results = runBlocking { |
156 | | - list.map { async(Dispatchers.IO) { it.getDetailApi() } }.awaitAll() |
157 | | - } |
158 | | - this.details = results.toMutableList() |
159 | | - project.messageBus.syncPublisher(FetchDartPackageFinishTopic).finish(results)//发送加载完成通知 |
160 | | - MyFileUtil.reIndexPubspecFile(project)//重新索引 |
161 | | - } |
162 | | - |
163 | | - |
164 | | - suspend fun startWithAsync(param: DartPackageTaskParam = DartPackageTaskParam()) { |
165 | | - val startTime = System.currentTimeMillis() // 获取起始时间 |
166 | | - this.details.clear() |
167 | | - val list = getPackageInfos() |
168 | | - val results = withContext(Dispatchers.IO) { |
169 | | - list.map { async(Dispatchers.IO) { it.getDetailApi() } }.awaitAll() |
170 | | - } |
171 | | - this.details = results.toMutableList() |
172 | | - val endTime = System.currentTimeMillis() // 获取结束时间 |
173 | | - scope.launch(Dispatchers.Main) { |
174 | | - project.messageBus.syncPublisher(FetchDartPackageFinishTopic).finish(results)///发送加载完成通知 |
175 | | - if (param.showNotification) { |
176 | | - getNotificationGroup()?.createNotification( |
177 | | - PluginBundle.get("refresh_success") + ", ${PluginBundle.get("package_size_is")}:${details.size} (${endTime - startTime}ms)", |
178 | | - NotificationType.INFORMATION |
179 | | - )?.notify(project) |
180 | | - } |
181 | | - param.complete?.invoke() |
182 | | - } |
183 | | - MyFileUtil.reIndexPubspecFile(project)//重新索引 |
184 | | - } |
185 | | - |
186 | | - |
187 | | - /** |
188 | | - * 重新索引 |
189 | | - */ |
190 | | - private suspend fun resetIndex(param: DartPackageTaskParam = DartPackageTaskParam()) { |
191 | | - startWithAsync(param) |
192 | | - } |
193 | | - |
194 | | - |
195 | | - fun startResetIndex(params: DartPackageTaskParam = DartPackageTaskParam()) { |
196 | | - scope.launch { |
197 | | - resetIndex(params) |
198 | | - } |
199 | | - } |
200 | | - |
201 | | - |
202 | | - override fun dispose() { |
203 | | - scope.cancel() |
204 | | - } |
205 | | - |
206 | | - /** |
207 | | - * 包数据加载完成事件 |
208 | | - */ |
209 | | - interface FetchDartPackageFinish { |
210 | | - fun finish(details: List<PubPackage>) |
211 | | - } |
212 | | - |
213 | | - companion object { |
214 | | - |
215 | | - |
216 | | - val FetchDartPackageFinishTopic: Topic<FetchDartPackageFinish> = |
217 | | - Topic.create("FetchDartPackageFinishTopic", FetchDartPackageFinish::class.java) |
218 | | - |
219 | | - /** |
220 | | - * 读取项目包操作模块的实例 |
221 | | - */ |
222 | | - @Deprecated("已弃用") |
223 | | - fun getInstance(project: Project): DartPackageCheckService { |
224 | | - return project.service<DartPackageCheckService>() |
225 | | - } |
226 | | - |
227 | | - |
228 | | - fun getNotificationGroup(): NotificationGroup? { |
229 | | - val id = "dart_package_check_service" |
230 | | - return NotificationGroupManager.getInstance().getNotificationGroup(id) |
231 | | - } |
232 | | - } |
233 | | -} |
234 | | - |
0 commit comments