Skip to content

Commit

Permalink
[feat] Run linting in the background.
Browse files Browse the repository at this point in the history
Add GitlabLintNotificationProvider for manually showing error notification.
  • Loading branch information
Blarc committed Jul 25, 2022
1 parent 9669b55 commit 7bdd4a7
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 54 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## [Unreleased]
### Added
- Throw exception when project id can not be retrieved.
- Run linting in the background.

## [0.0.11]
### Fixed
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

pluginGroup = com.github.blarc
pluginName = GitlabTemplateLint
pluginVersion = 0.0.11
pluginVersion = 0.0.12

# https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
pluginSinceBuild = 212
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ import java.util.concurrent.CompletableFuture
class GitlabLintRunner(private val project: Project) {

var status: LintStatusEnum = LintStatusEnum.WAITING
var gitlabLintResponse: GitlabLintResponse? = null

fun run(content: String, filePath: String): GitlabLintResponse? {
fun run(content: String, filePath: String){

updateStatusWidget(LintStatusEnum.RUNNING)

val repositoryManager = GitUtil.getRepositoryManager(project)
val repository = DvcsUtil.guessCurrentRepositoryQuick(project, repositoryManager, filePath)

if (repository != null) {
var result: GitlabLintResponse? = null
try {

val remoteUrl = getRemoteUrl(repository)
Expand All @@ -45,8 +45,8 @@ class GitlabLintRunner(private val project: Project) {
}

val branch = repository.currentBranch!!.name
gitlab.lintContent(content, projectId, branch).thenAccept { gitlabLintResponse ->
result = gitlabLintResponse
gitlab.lintContent(content, projectId, branch).thenAccept {
gitlabLintResponse = it
}.get()

}.get()
Expand All @@ -55,13 +55,13 @@ class GitlabLintRunner(private val project: Project) {
GitlabLintUtils.createNotification(project, e.localizedMessage?: "Unknown exception!")
}

if (result?.valid == true) updateStatusWidget(LintStatusEnum.VALID) else updateStatusWidget(LintStatusEnum.INVALID)
return result
if (gitlabLintResponse?.valid == true) updateStatusWidget(LintStatusEnum.VALID) else updateStatusWidget(LintStatusEnum.INVALID)
}
else {
updateStatusWidget(LintStatusEnum.INVALID)
gitlabLintResponse = null
GitlabLintUtils.createNotification(project, "File is not part of a Gitlab repository.")
}

updateStatusWidget(LintStatusEnum.INVALID)
GitlabLintUtils.createNotification(project, "File is not part of a Gitlab repository.")
return null
}

private fun updateStatusWidget(lintingStatus: LintStatusEnum) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.github.blarc.gitlab.template.lint.plugin

import com.github.blarc.gitlab.template.lint.plugin.settings.AppSettingsState
import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationType
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile

class GitlabLintUtils {
companion object{
Expand All @@ -12,5 +14,17 @@ class GitlabLintUtils {
.createNotification("Gitlab Lint", message, type)
.notify(project)
}

fun getGitlabLintRegex(): Regex {
val appSettingsState = AppSettingsState.instance
if (appSettingsState?.gitlabLintRegexString != null) {
return Regex(appSettingsState.gitlabLintRegexString!!)
}
return Regex(".*gitlab-ci\\.(yaml|yml)$")
}

fun matchesGitlabLintRegex(text: String): Boolean {
return getGitlabLintRegex().matches(text)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.github.blarc.gitlab.template.lint.plugin.inspections

import com.github.blarc.gitlab.template.lint.plugin.GitlabLintRunner
import com.github.blarc.gitlab.template.lint.plugin.GitlabLintUtils.Companion.matchesGitlabLintRegex
import com.github.blarc.gitlab.template.lint.plugin.settings.AppSettingsState
import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.components.service
import com.intellij.openapi.progress.runBackgroundableTask
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiFile
import com.intellij.ui.EditorNotifications

class GitlabLintInspector : LocalInspectionTool() {

override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : PsiElementVisitor() {
override fun visitFile(file: PsiFile) {
runBackgroundableTask("Gitlab Lint", file.project) {
it.isIndeterminate = true
val project = file.project
if (matchesGitlabLintRegex(file.name)) {
val gitlabToken = AppSettingsState.instance?.gitlabToken
if (gitlabToken != null && gitlabToken.isNotEmpty()) {
val linter = project.service<GitlabLintRunner>()
linter.run(file.text, file.virtualFile.path)
}
}
EditorNotifications.getInstance(project).updateAllNotifications()
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.github.blarc.gitlab.template.lint.plugin.inspections

import com.github.blarc.gitlab.template.lint.plugin.GitlabLintRunner
import com.github.blarc.gitlab.template.lint.plugin.GitlabLintUtils.Companion.matchesGitlabLintRegex
import com.github.blarc.gitlab.template.lint.plugin.widgets.LintStatusEnum
import com.intellij.codeInsight.hint.HintUtil
import com.intellij.openapi.components.service
import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.ui.EditorNotificationPanel
import com.intellij.ui.EditorNotifications

class GitlabLintNotificationProvider : EditorNotifications.Provider<EditorNotificationPanel>() {

companion object {
private val KEY = Key.create<EditorNotificationPanel>("GitlabLintNotificationProvider")
}

override fun getKey(): Key<EditorNotificationPanel> = KEY

override fun createNotificationPanel(
file: VirtualFile,
fileEditor: FileEditor,
project: Project
): EditorNotificationPanel? {

val gitlabRunner = project.service<GitlabLintRunner>()

if (gitlabRunner.status == LintStatusEnum.INVALID && matchesGitlabLintRegex(file.name)) {
val panel = EditorNotificationPanel(HintUtil.ERROR_COLOR_KEY)
panel.text = gitlabRunner.gitlabLintResponse?.errors.toString()
// TODO @Blarc: Implement error ignoring.
// panel.createActionLabel("Ignore this error.") {
// EditorNotifications.getInstance(project).updateAllNotifications()
// }

return panel
}
return null
}
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
package com.github.blarc.gitlab.template.lint.plugin.listeners

import com.github.blarc.gitlab.template.lint.plugin.settings.AppSettingsState
import com.github.blarc.gitlab.template.lint.plugin.GitlabLintUtils.Companion.matchesGitlabLintRegex
import com.github.blarc.gitlab.template.lint.plugin.widgets.LintStatusWidgetFactory
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.Service
import com.intellij.openapi.fileEditor.FileEditorManagerEvent
import com.intellij.openapi.fileEditor.FileEditorManagerListener
import com.intellij.openapi.wm.impl.status.widget.StatusBarWidgetSettings
import com.intellij.openapi.wm.impl.status.widget.StatusBarWidgetsManager
import com.intellij.ui.EditorNotifications
import org.jetbrains.kotlin.idea.util.application.getService

@Service
class GitlabLintFileEditorManagerListener : FileEditorManagerListener {

private val lintStatusWidgetFactory = ApplicationManager.getApplication().getService<LintStatusWidgetFactory>()
private val statusBarWidgetSettings = ApplicationManager.getApplication().getService<StatusBarWidgetSettings>()

var matches: Boolean = false
override fun selectionChanged(event: FileEditorManagerEvent) {

val project = event.manager.project

var regex = ".*gitlab-ci\\.(yaml|yml)$"
val appSettingsState = AppSettingsState.instance
if (appSettingsState?.gitlabLintRegexString != null) {
regex = appSettingsState.gitlabLintRegexString!!
}

var matches = false
// Check if file matches regex
if (event.newFile != null) {
matches = Regex(regex).matches(event.newFile.name)
matches = matchesGitlabLintRegex(event.newFile.name)
}

val lintStatusWidgetFactory = ApplicationManager.getApplication().getService<LintStatusWidgetFactory>()
val statusBarWidgetSettings = ApplicationManager.getApplication().getService<StatusBarWidgetSettings>()
// Hide/show error notification
EditorNotifications.getInstance(project).updateAllNotifications()

// Hide/show widget
val statusBarWidgetsManager = project.getService<StatusBarWidgetsManager>()

if (lintStatusWidgetFactory != null) {
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,13 @@
groupBundle="messages.InspectionsBundle"
groupKey="group.names.probable.bugs"
enabledByDefault="true"
implementationClass="com.github.blarc.gitlab.template.lint.plugin.GitlabLintInspector"
implementationClass="com.github.blarc.gitlab.template.lint.plugin.inspections.GitlabLintInspector"
displayName="Linting"
shortName="GitlabLint"
runForWholeFile="true" />

<editorNotificationProvider implementation="com.github.blarc.gitlab.template.lint.plugin.inspections.GitlabLintNotificationProvider"/>

<postStartupActivity implementation="com.github.blarc.gitlab.template.lint.plugin.GitlabPostStartupActivity" />

<notificationGroup
Expand Down

0 comments on commit 7bdd4a7

Please sign in to comment.