Skip to content

Commit f6271ab

Browse files
committed
refactor(snippet): improve devcontainer.json detection logic #308
- Add content parameter to `updateForDevContainer` for better validation. - Enhance devcontainer detection by checking for specific properties and file content. - Simplify file creation logic and improve schema provider filtering.
1 parent f45c822 commit f6271ab

File tree

1 file changed

+35
-17
lines changed

1 file changed

+35
-17
lines changed

core/src/main/kotlin/cc/unitmesh/devti/gui/snippet/AutoDevLanguageLabelAction.kt

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package cc.unitmesh.devti.gui.snippet
22

33
import cc.unitmesh.devti.util.parser.CodeFence
4-
import com.intellij.ide.scratch.ScratchRootType
54
import com.intellij.json.JsonLanguage
65
import com.intellij.json.psi.JsonFile
76
import com.intellij.json.psi.JsonLiteral
@@ -20,7 +19,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
2019
import com.intellij.openapi.project.DumbAwareAction
2120
import com.intellij.openapi.project.Project
2221
import com.intellij.openapi.util.Key
23-
import com.intellij.openapi.vfs.VirtualFile
22+
import com.intellij.openapi.util.NlsSafe
2423
import com.intellij.psi.PsiFile
2524
import com.intellij.psi.PsiManager
2625
import com.intellij.testFramework.LightVirtualFile
@@ -59,7 +58,8 @@ class AutoDevLanguageLabelAction : DumbAwareAction(), CustomComponentAction {
5958

6059
val project = e.project ?: return
6160
if (lightVirtualFile.language == JsonLanguage.INSTANCE) {
62-
lightVirtualFile = updateForDevContainer(project, lightVirtualFile) ?: lightVirtualFile
61+
val content = editor.document.text
62+
lightVirtualFile = updateForDevContainer(project, lightVirtualFile, content) ?: lightVirtualFile
6363
}
6464

6565
val displayName =
@@ -69,33 +69,51 @@ class AutoDevLanguageLabelAction : DumbAwareAction(), CustomComponentAction {
6969

7070
private fun updateForDevContainer(
7171
project: Project,
72-
lightVirtualFile: LightVirtualFile
72+
lightVirtualFile: LightVirtualFile,
73+
content: String
7374
): LightVirtualFile? {
75+
// 判断文件名是否已经是 devcontainer 相关
76+
val fileName = lightVirtualFile.name.lowercase()
77+
if ((!content.startsWith("{") && !content.endsWith("}"))) return null
78+
79+
if (fileName == "devcontainer.json" || fileName.contains("devcontainer")) {
80+
return lightVirtualFile
81+
}
82+
7483
val psiFile = runReadAction { PsiManager.getInstance(project).findFile(lightVirtualFile) } ?: return null
75-
val image = getEnvObject("image", psiFile) ?: return null
84+
val rootObject = (psiFile as? JsonFile)?.topLevelValue as? JsonObject ?: return null
7685

77-
val literal = image as? JsonStringLiteral ?: return null
78-
val imageValue = literal.value
86+
val hasDevContainerProps = rootObject.propertyList.any {
87+
val propName = it.name
88+
propName == "image" || propName == "dockerFile" || propName == "containerEnv" ||
89+
propName == "remoteUser" || propName == "customizations" || propName == "features"
90+
}
91+
92+
if (!hasDevContainerProps) return null
7993

80-
if (!imageValue.contains("mcr.microsoft.com/devcontainers")) return null
94+
val image = getEnvObject("image", psiFile) as? JsonStringLiteral
95+
val dockerfile = getEnvObject("dockerFile", psiFile) as? JsonStringLiteral
96+
val remoteUser = getEnvObject("remoteUser", psiFile) as? JsonStringLiteral
97+
98+
val isDevContainer = when {
99+
image != null && image.value.contains("mcr.microsoft.com/devcontainers") -> true
100+
dockerfile != null -> true
101+
remoteUser != null -> true
102+
rootObject.propertyList.size >= 3 && hasDevContainerProps -> true
103+
else -> false
104+
}
81105

82-
/// create new file with name devcontainer.json
83-
val content = lightVirtualFile.inputStream.readBytes().toString(Charsets.UTF_8)
84-
val newFile = LightVirtualFile(
85-
"devcontainer.json",
86-
JsonLanguage.INSTANCE,
87-
content
88-
)
106+
if (!isDevContainer) return null
107+
val newFile = LightVirtualFile("devcontainer.json", JsonLanguage.INSTANCE, content)
89108

90109
try {
91110
// follow: https://containers.dev/guide/dockerfile
92111
// check image, exist, {
93112
// "image": "mcr.microsoft.com/devcontainers/base:ubuntu"
94113

95114
val providers = JsonSchemaProviderFactory.EP_NAME.extensions.map { it.getProviders(project) }.flatten()
96-
.filter { it.isAvailable(lightVirtualFile) }
115+
.filter { it.isAvailable(newFile) }
97116

98-
// devcontainer.json
99117
providers.map {
100118
it.name
101119
}

0 commit comments

Comments
 (0)