Skip to content

Commit

Permalink
Merge pull request #10 from dinbtechit/feature/8-2-support-Multiproje…
Browse files Browse the repository at this point in the history
…ct-workspace

Fix for #2 and #8
  • Loading branch information
dinbtechit authored Oct 26, 2024
2 parents 5af8213 + ef04931 commit f6ef762
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 24 deletions.
1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

## [Unreleased]
### Added
- #2 - [Feature] adding support for monorepos
- #8 - [Feature] - can't work in pnpm workspace bug

## [0.0.2]
### Added
- New Menu for creating controller, module and service
- New File Icons for NestJS.

Expand Down
5 changes: 4 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pluginGroup = com.github.dinbtechit.jetbrainsnestjs
pluginName = jetbrains-nestjs
pluginRepositoryUrl = https://github.com/dinbtechit/jetbrains-nestjs
# SemVer format -> https://semver.org
pluginVersion = 0.0.2
pluginVersion = 0.0.3

# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
pluginSinceBuild = 223
Expand Down Expand Up @@ -32,3 +32,6 @@ org.gradle.caching = true

# Enable Gradle Kotlin DSL Lazy Property Assignment -> https://docs.gradle.org/current/userguide/kotlin_dsl.html#kotdsl:assignment
systemProp.org.gradle.unsafe.kotlin.assignment = true

systemProp.gradle.internal.http.ignoreSslErrors=true
systemProp.com.sun.net.ssl.checkRevocation=false
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
}

rootProject.name = "IntelliJ Platform Plugin Template"
rootProject.name = "Jetbrains NestJS"
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.intellij.openapi.components.service
import com.intellij.openapi.editor.event.DocumentEvent
import com.intellij.openapi.editor.event.DocumentListener
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.guessProjectDir
import com.intellij.openapi.ui.ComboBox
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.openapi.ui.ValidationInfo
Expand Down Expand Up @@ -61,24 +62,25 @@ class GenerateCLIDialog(private val project: Project, val e: AnActionEvent, val
"No module found to update",
AllIcons.General.Warning, JBLabel.LEFT
)
private val virtualFile: VirtualFile = e.getRequiredData(CommonDataKeys.VIRTUAL_FILE)
private val directory = when {
private val virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE)

private val directory = if (virtualFile != null )when {
virtualFile.isDirectory -> virtualFile // If it's directory, use it
else -> virtualFile.parent // Otherwise, get its parent directory
}
} else project.guessProjectDir()

init {
title = if (type != null) "Nest ${type.capitalize()} Generate" else "Nest CLI/Schematics Generate"
val state = nestStoreService.store.getState()
comboBox.item = type ?: (state.type ?: "controller")
autoCompleteField.text = if (type == null) state.parameter else ""
generatePath.text = NestGeneratorFileUtil.computeGeneratePath(comboBox.item, project, directory)
generatePath.text = NestGeneratorFileUtil.computeGeneratePath(comboBox.item, project, directory!!)
generatePath.isEnabled = false
moduleInfoLabel.text = """<html><b>Updates Module:</b>
|${
NestGeneratorFileUtil.getRelativePath(
project,
NestGeneratorFileUtil.findClosestModuleFile(project, e, directory)
NestGeneratorFileUtil.findClosestModuleFile(project, e, directory!!)
)
} </html>
|""".trimMargin()
Expand Down Expand Up @@ -187,7 +189,7 @@ class GenerateCLIDialog(private val project: Project, val e: AnActionEvent, val
Action.GenerateCLIAction(
type = type ?: comboBox.item,
options = autoCompleteField.text,
filePath = NestGeneratorFileUtil.getFilePath(project, e, directory),
filePath = NestGeneratorFileUtil.getFilePath(project, e, directory!!),
project = project,
generateInDir = directory,
closestModuleDir = NestGeneratorFileUtil.findClosestModuleFileDir(project, e, directory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import com.github.dinbtechit.jetbrainsnestjs.actions.cli.store.CLIState
import com.github.dinbtechit.jetbrainsnestjs.common.nestProject.NestProject
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.service
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.vfs.VirtualFile


class NestjsCliAction : DumbAwareAction(NestIcons.logo) {
Expand Down Expand Up @@ -35,7 +37,7 @@ class NestjsCliAction : DumbAwareAction(NestIcons.logo) {
// Display action only if it is a nest project.
val project = e.project
val nestProject = project?.service<NestProject>()
e.presentation.isEnabledAndVisible = nestProject?.isNestProject(project) == true
nestProject?.showContextMenu(e)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.github.dinbtechit.jetbrainsnestjs.actions.cli.store.CLIState
import com.github.dinbtechit.jetbrainsnestjs.common.nestProject.NestProject
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.service
import com.intellij.openapi.project.DumbAwareAction
Expand Down Expand Up @@ -35,7 +36,7 @@ class NestControllerCLIAction : DumbAwareAction(NestIcons.FileTypeController) {
// Display action only if it is a nest project.
val project = e.project
val nestProject = project?.service<NestProject>()
e.presentation.isEnabledAndVisible = nestProject?.isNestProject(project) == true
nestProject?.showContextMenu(e)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.github.dinbtechit.jetbrainsnestjs.actions.cli.store.CLIState
import com.github.dinbtechit.jetbrainsnestjs.common.nestProject.NestProject
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.service
import com.intellij.openapi.project.DumbAwareAction
Expand Down Expand Up @@ -35,7 +36,7 @@ class NestModuleCLIAction : DumbAwareAction(NestIcons.FileTypeModule) {
// Display action only if it is a nest project.
val project = e.project
val nestProject = project?.service<NestProject>()
e.presentation.isEnabledAndVisible = nestProject?.isNestProject(project) == true
nestProject?.showContextMenu(e)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.github.dinbtechit.jetbrainsnestjs.actions.cli.store.CLIState
import com.github.dinbtechit.jetbrainsnestjs.common.nestProject.NestProject
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.service
import com.intellij.openapi.project.DumbAwareAction
Expand Down Expand Up @@ -35,6 +36,6 @@ class NestServiceCLIAction : DumbAwareAction(NestIcons.FileTypeService) {
// Display action only if it is a nest project.
val project = e.project
val nestProject = project?.service<NestProject>()
e.presentation.isEnabledAndVisible = nestProject?.isNestProject(project) == true
nestProject?.showContextMenu(e)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package com.github.dinbtechit.jetbrainsnestjs.actions.cli.util

import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.guessProjectDir
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.FilenameIndex
import com.intellij.psi.search.GlobalSearchScope
import java.nio.file.Paths

object NestGeneratorFileUtil {
Expand All @@ -24,7 +27,7 @@ object NestGeneratorFileUtil {
}

fun findClosestModuleFile(project: Project, e: AnActionEvent, workingDir: VirtualFile): VirtualFile {
val virtualFile: VirtualFile = e.getRequiredData(CommonDataKeys.VIRTUAL_FILE)
val virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE)
return recursivelyFindModuleInParentFolders(virtualFile) ?: workingDir
}

Expand Down Expand Up @@ -73,4 +76,8 @@ object NestGeneratorFileUtil {

return relativePath.toString()
}

fun getAllNestCliFiles(project: Project): Collection<VirtualFile> {
return FilenameIndex.getVirtualFilesByName(project, "nest-cli.json", GlobalSearchScope.projectScope(project))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,73 @@ import com.intellij.javascript.nodejs.interpreter.NodeJsInterpreterManager
import com.intellij.javascript.nodejs.util.NodePackage
import com.intellij.lang.javascript.JavaScriptBundle
import com.intellij.lang.javascript.boilerplate.NpmPackageProjectGenerator
import com.intellij.lang.javascript.buildTools.npm.PackageJsonUtil
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.guessProjectDir
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import java.nio.file.Files
import java.nio.file.Paths
import com.intellij.psi.PsiFile
import com.intellij.psi.search.FilenameIndex
import com.intellij.psi.search.GlobalSearchScope

@Service(Service.Level.PROJECT)
class NestProject {

fun isNestProject(project: Project?): Boolean {
val isProjectOpen = project != null && !project.isDisposed
var isFileExists = false

if (isProjectOpen) {
assert(project != null)
val projectDirectory: VirtualFile = project!!.guessProjectDir()!!
val filePath = Paths.get(projectDirectory.path, "nest-cli.json")
isFileExists = Files.exists(filePath)
return isFileExists
return getAllNestJSCliFiles(project!!).isNotEmpty()
}
return false
}

fun showContextMenu(e: AnActionEvent) {
val project = e.project
val nestProject = project?.service<NestProject>()
val virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE)
if (project == null || virtualFile == null) {
e.presentation.isEnabledAndVisible = false // Disable the action if required data is unavailable
return
}
e.presentation.isEnabledAndVisible = nestProject?.isWithinNestProjectFolder(e) == true
}

private fun isWithinNestProjectFolder(e: AnActionEvent): Boolean {
val virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE)

if (e.project == null || virtualFile == null) return false

val directory = when {
virtualFile.isDirectory -> virtualFile // If it's directory, use it
else -> virtualFile.parent // Otherwise, get its parent directory
}
val nestCliFiles = getAllNestJSCliFiles(e.project!!)
for (showContext in nestCliFiles) {
if (directory.path.contains(showContext.parent.path)) {
return true
}
}
return false
}

fun isFileWithinNestProject(file: PsiFile): Boolean {
val nestCliFiles = getAllNestJSCliFiles(file.project)
for (showContext in nestCliFiles) {
if (file.virtualFile.path.contains(showContext.parent.path)) {
return true
}
}
return false
}

private fun getAllNestJSCliFiles(project: Project): MutableCollection<VirtualFile> {
return FilenameIndex.getVirtualFilesByName("nest-cli.json", GlobalSearchScope.projectScope(project))
}

fun runGenerator(
project: Project,
schematic: GenerateCLIState
Expand All @@ -45,7 +86,9 @@ class NestProject {
val modules: MutableList<CompletionModuleInfo> = mutableListOf()
val cli: VirtualFile = project.guessProjectDir()!!

NodeModuleSearchUtil.findModulesWithName(modules, "@nestjs/cli", cli, null)
val closestPackageJsonFile = PackageJsonUtil.findUpPackageJson(schematic.generateInDir!!)

NodeModuleSearchUtil.findModulesWithName(modules, "@nestjs/cli", closestPackageJsonFile, null)

val module = modules.firstOrNull() ?: return
val parameters = schematic.parameter.split(" ")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class NestConfigFileIconProvider : IconProvider(), DumbAware {
override fun getIcon(element: PsiElement, flags: Int): Icon? {
val fileElement = element as? PsiFile
val nestProject = element.project.service<NestProject>()
return if (fileElement != null && nestProject.isNestProject(element.project)) {
return if (fileElement != null && nestProject.isFileWithinNestProject(fileElement)) {
when {
fileElement.name.equals("nest-cli.json", true) -> NestIcons.FileType
fileElement.name.contains(".controller.ts", true) -> NestIcons.FileTypeController
Expand Down

0 comments on commit f6ef762

Please sign in to comment.