插件初始化
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
# Idea-Plugin(IntelliJ IDEA 插件)
|
||||
|
||||
在 IDEA 内提供:**Proto → Java 命令类**、**MySQL → JPA 实体**、**Java 类 ↔ JSON**、**按项目保存的备忘录**、**提交前本机时间校验**。
|
||||
|
||||
---
|
||||
|
||||
## 功能一览
|
||||
|
||||
| 功能 | 主要入口 | 说明 |
|
||||
|------|----------|------|
|
||||
| Proto 转 Java | 右键 `.proto`、项目树、**Tools** | 从 proto 生成 `@Cmd` 命令类 |
|
||||
| mysql 转 Jpa | 右键**文件夹**、**Tools** | 连接 MySQL,多表生成 JPA 实体 |
|
||||
| Java → JSON | 类名上 **Alt+Enter**、编辑器右键 | 按字段类型生成带默认值的 JSON |
|
||||
| Json 转 java | 右键**文件夹**、**Tools** | 从 JSON 生成 Java Bean 源文件 |
|
||||
| 我的自定义备忘录 | **Tools**、工具窗口 | 按项目保存备忘录 |
|
||||
| 提交前时间校验 | 提交 / 提交并推送 | 本机时间与网络时间偏差过大时警告 |
|
||||
|
||||
---
|
||||
|
||||
## 1. Proto 转 Java
|
||||
|
||||
**做什么**:从 `cmd_rpc.proto`(及同目录可选的 `pb_service.proto`)解析 `ServiceNService` 与 `rpc`,在指定目录生成与 **comm-framework** 风格一致的 `@Cmd` + `AbstractTypedPbCommand` Java 类。
|
||||
|
||||
**怎么用**
|
||||
|
||||
1. 打开符合约定的 `.proto`(可与 `pb_service.proto` 同目录)。
|
||||
2. **Proto转Java**(编辑器或项目树右键选中 `.proto`,或 **Tools** 菜单)。
|
||||
3. 在对话框中勾选 RPC、选择输出目录(如 `.../src/main/java/.../cmd/cmds`)。
|
||||
4. 确认生成;已存在的同名 `.java` 会**跳过**。
|
||||
|
||||
**实现要点**
|
||||
|
||||
- 入口:`ProtoCmdGeneratorAction`;对话框 `GenerateCmdDialog`;生成逻辑 `ProtoFileParser`、`JavaCommandGenerator` 等。
|
||||
- 输出:通过 `PsiFileFactory` + `WriteCommandAction` 在目标目录创建 `.java` 文件。
|
||||
|
||||
**约定**(Proto)
|
||||
|
||||
- **Service 命名**:`Service1Service`、`Service2Service`、…
|
||||
- **Method 枚举**:同文件内 `ServiceN_Method`,去掉 `Default*` 后按枚举值从小到大与同一 service 内 **rpc 声明顺序** 对应。
|
||||
- **PbService**:同目录 `pb_service.proto` 的 `enum PbService` 中 `= N` 的项名;缺失时回退为 `Service_N`。
|
||||
|
||||
---
|
||||
|
||||
## 2. mysql 转 Jpa
|
||||
|
||||
**做什么**:连接 MySQL,列出库表(支持搜索与多选),按表结构生成带 **`jakarta.persistence`** 注解的实体类(`@Entity`、`@Table`、`@Id`、`@Column` 等;复合主键生成 `@IdClass`)。
|
||||
|
||||
**怎么用**
|
||||
|
||||
1. 在 **Java 源码目录**(如 `.../src/main/java/你的包路径`)上**右键文件夹**打开对话框,或从 **Tools** 打开(需在对话框中理解输出目录与包名推断规则)。
|
||||
2. 填写 JDBC(**必须含库名**,例如 `host:3306/your_db` 或完整 `jdbc:mysql://.../your_db?...`)、用户名、密码。
|
||||
3. **查询表** → 搜索 / 多选表 → **生成 Java 实体**。
|
||||
|
||||
**实现要点**
|
||||
|
||||
- 入口:`MysqlEntityFromFolderAction`;对话框与写文件:`mysql` 包下 `MysqlEntityDialog`、实体生成器等。
|
||||
- JDBC:插件依赖 `mysql-connector-j`;URL 须包含库名。
|
||||
- 包名:优先根据所选目录相对 `src/main/java` 的路径推断(`PackageInference`)。
|
||||
- 若目标工程仍为 Spring Boot 2 / `javax.persistence`,生成代码中的包名需自行替换或改生成器。
|
||||
|
||||
---
|
||||
|
||||
## 3. Java 类 → JSON(默认值)
|
||||
|
||||
**做什么**:根据当前 Java 类的**非 static 实例字段**(含继承字段)生成一段 **JSON**,各类型使用约定**默认值**(数字 0、布尔 false、字符串 `""`、集合 `[]`、Map `{}`、嵌套类型递归为对象;循环引用处为 `null` 等)。
|
||||
|
||||
**怎么用**
|
||||
|
||||
1. **推荐**:光标放在**类声明上的类名**(例如 `public class Foo` 中的 `Foo`),按 **Alt+Enter**,选择 **「是否生成 JSON(默认值)…」**。
|
||||
2. 在确认对话框中选 **是**。
|
||||
3. 在结果弹窗中查看 JSON,可点击 **「复制到剪贴板」**。
|
||||
|
||||
**备选**:光标在类体内任意位置时,编辑器 **右键** → **「生成类JSON(默认值)」**,流程相同(先确认再弹窗)。
|
||||
|
||||
**实现要点**
|
||||
|
||||
- 意图:`ClassToJsonIntention`(注册于 `plugin.xml` 的 `intentionAction`,说明见 `intentionDescriptions/ClassToJsonIntention/`)。
|
||||
- 编辑器菜单:`GenerateClassJsonEditorAction`。
|
||||
- 构建 JSON:`JavaClassToJsonBuilder`(PSI 字段与类型 + Gson 格式化);展示:`ShowJsonResultDialog`。
|
||||
|
||||
---
|
||||
|
||||
## 4. Json 转 java
|
||||
|
||||
**做什么**:根据输入的 **JSON 对象**(根节点必须是 `{}`)和 **Java 类名**,在选定目录生成一个 **Java Bean** 源文件:`private` 字段 + getter/setter;嵌套对象生成 **静态内部类**;数组字段推断为 `List<…>`(元素类型主要依据**数组第一个元素**)。
|
||||
|
||||
**怎么用**
|
||||
|
||||
1. 在项目树中**右键目标文件夹**(一般为 `src/main/java/...` 下某包目录),或使用 **Tools** → **Json转java**(须已能确定输出目录;若未选文件夹会提示)。
|
||||
2. 填写 **类名**(不含 `.java`)、**包名**(默认按目录用 `PackageInference` 推断)。
|
||||
3. 粘贴 **JSON**(根为对象)。
|
||||
4. 确定后生成 `类名.java`;若文件已存在则**不覆盖**并提示。
|
||||
|
||||
**实现要点**
|
||||
|
||||
- 入口:`JsonToJavaAction`;对话框:`JsonToJavaDialog`;解析与代码生成:`JsonToJavaGenerator`(Gson 解析);字段名规则复用 `mysql/JavaNames`。
|
||||
- 依赖:Gson(`build.gradle.kts`)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 我的自定义备忘录
|
||||
|
||||
**做什么**:右侧工具窗口,对当前 **项目** 做备忘录的增删改(新建、编辑后保存、删除)。
|
||||
|
||||
**怎么用**
|
||||
|
||||
1. **Tools** → **我的自定义备忘录**;或在 **View → Tool Windows** 中找到同名窗口。
|
||||
2. **新建** → 填写标题与正文 → **保存**;选中条目可 **删除**。
|
||||
3. 切换列表项前请先 **保存** 当前编辑,避免未写入的修改被覆盖。
|
||||
|
||||
**实现要点**
|
||||
|
||||
- 工具窗口:`memo/MemoToolWindowFactory` 等;持久化:`MemoProjectService` + `.idea/protoPluginMemos.xml`。
|
||||
- 工具窗口 ID:`MyCustomMemo`(与 `plugin.xml` 中一致)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 提交前时间校验(Commit / Commit & Push)
|
||||
|
||||
**做什么**:在 **提交** 或 **提交并推送** 前,用 HTTP 响应头里的 `Date` 作为参考时间,与 **本机系统时间** 比较;偏差超过 **1 分钟** 时弹出警告,用户可选择继续或取消本次提交。
|
||||
|
||||
**怎么用**
|
||||
|
||||
- 正常走 IDE 的 **Commit** / **Commit and Push** 即可;无单独菜单。若本机时间与网络时间相差过大,会看到警告对话框。
|
||||
|
||||
**实现要点**
|
||||
|
||||
- `CommitTimeCheckinHandlerFactory` 注册 `CheckinHandler`;实际校验在 Kotlin `TimeSkewCommitCheckHandler`(`CommitCheck`,**`ExecutionOrder.EARLY`**)。
|
||||
- 使用 EARLY 是为避免默认 LATE 检查在部分场景下触发 **ABORTED → Cancelled**,表现为提交界面异常或文件被回退。
|
||||
- 无法访问外网、拿不到参考时间时:**不拦截**。Shelf、Create Patch 等本地提交执行器通常不跑该校验。
|
||||
|
||||
---
|
||||
|
||||
## 环境
|
||||
|
||||
- JDK **17**
|
||||
- IntelliJ IDEA **2023.3.x Ultimate**(与 `sinceBuild` 233 等对齐);`gradle.properties` 可配置 `ideaLocalPath` 指向本机安装目录,`runIde` 沙盒使用该 IDEA。若路径不同请修改;未配置时 Gradle 会尝试在线解析 `2023.3` + `IU`。
|
||||
- **运行沙箱**:若仓库含 Gradle Wrapper,可用 `./gradlew runIde`;若无 wrapper,可用本机已安装的 Gradle 执行相同任务(见下节)。
|
||||
|
||||
### 国内镜像(已配置)
|
||||
|
||||
- **Gradle Wrapper**:若存在 `gradle/wrapper/gradle-wrapper.properties`,可使用腾讯云等镜像与合适发行版(如 `gradle-8.5-all.zip` 或 `bin.zip`)。
|
||||
- **Maven / 插件仓库**:`settings.gradle.kts` 与 `build.gradle.kts` 已优先阿里云等公共仓库。
|
||||
- **IntelliJ Platform SDK**:国内常因 CloudFront 导致 `UnknownHostException`;**推荐配置 `ideaLocalPath` 或 `IDEA_LOCAL_PATH`**,避免下载 `ideaIU`。
|
||||
|
||||
### `ideaLocalPath` 在 Program Files 时:拒绝访问
|
||||
|
||||
`gradle-intellij-plugin` 使用本机 IDE 时可能在安装目录写入 Ivy/builtin 元数据;`C:\Program Files\…` 可能不可写。
|
||||
|
||||
**处理**:将 IDEA 装到用户目录(Toolbox)、或复制到可写盘,再把 `ideaLocalPath` 指到该根目录(含 `lib`、`plugins`)。
|
||||
|
||||
### Gradle JVM
|
||||
|
||||
`gradle-intellij-plugin` 1.17.x 需 **JDK 11+**;本项目源码为 **17**。IDEA 中 **Settings → Gradle → Gradle JVM** 请选择 17。
|
||||
|
||||
### runIde 启动日志里的告警/异常(多与本插件代码无关)
|
||||
|
||||
| 现象 | 常见原因 | 建议处理 |
|
||||
|------|----------|----------|
|
||||
| `VFS wasn't safely shut down`、`Content storage... broken`、`LocalHistory is lost` | 上次沙箱里的 IDEA **未正常退出**,虚拟文件系统缓存损坏 | 清沙箱后重跑(见下) |
|
||||
| `GradleJvmSupportMatrix` + `IllegalArgumentException: 25`(`JavaVersion.parse`) | 沙箱内 **Gradle 插件** 持久化配置损坏,或与 2023.3 内置解析逻辑冲突 | 清沙箱后重跑 |
|
||||
| `LoadingState` / `Should be called at least in the state COMPONENTS_LOADED`(`Registry`) | **平台**在极早启动阶段被 VFS 刷新等并发触发,属 IDE 内部时序问题 | 一般可忽略;清沙箱可减轻连带问题 |
|
||||
| `Watch roots should be absolute: src/main/java` | **当前打开的业务工程**里模块源根被记成相对路径,`.iml`/导入异常 | 在**该工程**中 **Gradle/Maven Reload** 或重新导入 |
|
||||
| `Project ... not trusted enough` | 沙箱安全策略未信任项目 | 在沙箱 IDEA 里对该工程点 **Trust Project** |
|
||||
|
||||
**清沙箱(推荐):**
|
||||
|
||||
```bash
|
||||
./gradlew cleanIdeaSandbox runIde
|
||||
```
|
||||
|
||||
或先删目录再运行:`build/idea-sandbox`(Windows 下路径为 `build\idea-sandbox`)。
|
||||
|
||||
**每次 runIde 前自动清沙箱(可选,会丢掉沙箱里的设置与最近打开的工程记录):**
|
||||
|
||||
```bash
|
||||
./gradlew runIde -PfreshSandbox
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 构建插件 ZIP
|
||||
|
||||
```bash
|
||||
./gradlew buildPlugin
|
||||
```
|
||||
|
||||
若无 `gradlew`,使用本机 Gradle:
|
||||
|
||||
```bash
|
||||
gradle buildPlugin
|
||||
```
|
||||
|
||||
产物在 **`build/distributions/`**(一般为 `Idea-Plugin-<version>.zip`),在 IDEA **Settings → Plugins → Install Plugin from Disk** 安装。
|
||||
|
||||
若 **`build` / `buildPlugin` 在 `:buildSearchableOptions` 阶段报错**(如 `sun.font.Font2D.getTypographicFamilyName` / `NoSuchMethodError`),多半是 **跑该任务的 Java 与 IDEA 自带 JBR 版本不一致**。本仓库在 `build.gradle.kts` 的 `tasks { named("buildSearchableOptions") { enabled = false } }` 中禁用了该任务;一般插件不需要生成该项。若你必须开启,请删除上述配置并让 **Gradle JVM** 使用安装目录下的 **`jbr`** 再试。
|
||||
|
||||
---
|
||||
|
||||
## 项目结构(主要源码)
|
||||
|
||||
| 路径 | 说明 |
|
||||
|------|------|
|
||||
| `ProtoCmdGeneratorAction` / `GenerateCmdDialog` / `JavaCommandGenerator` | Proto → Cmd 生成 |
|
||||
| `MysqlEntityFromFolderAction` / `mysql/*` | MySQL 元数据与 JPA 源码生成 |
|
||||
| `json/*` | Java→JSON(PSI + Gson)、JSON→Java(对话框 + 生成器)、意图与编辑器 Action |
|
||||
| `PackageInference` | 由目录路径推断 Java 包名 |
|
||||
| `memo/*` | 备忘录状态与工具窗口 UI |
|
||||
| `vcs/*` | 提交前时间校验(`CheckinHandlerFactory` + Kotlin `CommitCheck` EARLY) |
|
||||
| `META-INF/plugin.xml` | 插件描述、Action、Tool Window、Intention、Project Service |
|
||||
Reference in New Issue
Block a user