diff --git a/.gitignore b/.gitignore index 472f234f32d4e8ac11af53c174a701aef2c1f70a..defebe3d68fd822914e05de79f2a01ce5d6727be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.iml .gitignore .gradle +.vscode /local.properties /.idea/caches /.idea/libraries @@ -22,4 +23,6 @@ /src/generator/resources/cmds/linux/napi_generator-linux /src/generator/resources/cmds/mac/napi_generator-macos /src/generator/resources/cmds/win/napi_generator-win.exe -/src/generator/.idea/ \ No newline at end of file +/src/generator/.idea/ +/src/package-lock.json +/src/package.json diff --git a/figures/IntelliJ_env_Proj_Module.png b/figures/IntelliJ_env_Proj_Module.png new file mode 100644 index 0000000000000000000000000000000000000000..5b7cd4c353f7562b238d93b169773cb5acebac19 Binary files /dev/null and b/figures/IntelliJ_env_Proj_Module.png differ diff --git a/figures/IntelliJ_env_Proj_Module_New.png b/figures/IntelliJ_env_Proj_Module_New.png new file mode 100644 index 0000000000000000000000000000000000000000..d8c180413b38fbd8e8e5c21116612ea400671f07 Binary files /dev/null and b/figures/IntelliJ_env_Proj_Module_New.png differ diff --git a/figures/IntelliJ_env_config_SDKs.png b/figures/IntelliJ_env_config_SDKs.png new file mode 100644 index 0000000000000000000000000000000000000000..0d88eb74c03bcf7f42a33dd3181de767317bb3b4 Binary files /dev/null and b/figures/IntelliJ_env_config_SDKs.png differ diff --git a/figures/IntelliJ_env_config_open_proj.png b/figures/IntelliJ_env_config_open_proj.png new file mode 100644 index 0000000000000000000000000000000000000000..c38a5a1334b8ef27c639ebd8a0b5b39a00e0df5f Binary files /dev/null and b/figures/IntelliJ_env_config_open_proj.png differ diff --git a/figures/IntelliJ_env_deveco_install.png b/figures/IntelliJ_env_deveco_install.png new file mode 100644 index 0000000000000000000000000000000000000000..17cb2a8195b816dddb3785bacb8005ce664abd4a Binary files /dev/null and b/figures/IntelliJ_env_deveco_install.png differ diff --git a/figures/IntelliJ_env_module_root.png b/figures/IntelliJ_env_module_root.png new file mode 100644 index 0000000000000000000000000000000000000000..54a4fc527fad7e7d240ee4e19e63c8bc436cf9dc Binary files /dev/null and b/figures/IntelliJ_env_module_root.png differ diff --git a/figures/IntelliJ_env_proj_structure.png b/figures/IntelliJ_env_proj_structure.png new file mode 100644 index 0000000000000000000000000000000000000000..a350777a80478065ae1de06f6ff723dae6a3136a Binary files /dev/null and b/figures/IntelliJ_env_proj_structure.png differ diff --git a/src/generator/README_zh.md b/src/generator/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..a3202496d6206cb58831fbbf27fd1c3ba90d90f9 --- /dev/null +++ b/src/generator/README_zh.md @@ -0,0 +1,42 @@ +# IDEA插件开发环境配置 + +基础环境要求: +JDK 11 ,IDEA Community 2021.3.3 + +1.下载IDEA Community 与 JDK11 配置好环境 +点击 https://www.jetbrains.com/idea/download/ 下载Community版本,并完成安装。 + + +2.打开IDEA Community 应用程序。 +依次点击项目File>Open 选择napi_generator/src/generator项目文件夹。 +![](../../figures/IntelliJ_env_config_open_proj.png) + +3.项目配置 +项目打开完成,点击File>Project Structure +![](../../figures/IntelliJ_env_proj_structure.png) + + +4.配置Modules. +Project Settings > Modules 新建Modules.点击上方“-”删除原有的Modules,“+”选择 New Modules。 +![](../../figures/IntelliJ_env_Proj_Module.png) + + +5.配置Module SDK. +在New Modules对话框中,选择IntelliJ Platform Plugin。若为首次环境配置,请在Module SDK 下拉框中点击 Add IntelliJ Platform Plugin SDK 选择IDEA Community安装目录,点击OK,在Select Internal Java Platform 选择 JAVA SDK 11(213版本只支持 11) +![](../../figures/IntelliJ_env_Proj_Module_New.png) + +6.配置Root Content. +在上图界面点击Next,选择Content root:为napi_generator/src/generator文件夹,module name会自动变为generator,若出现提示已存在是否覆盖的提示,请点“是”完成配置。 +![](../../figures/IntelliJ_env_module_root.png) + + +7.配置完成Modules后,若在SDKs中无相应JDK和Plugin SDK,请点击+号分别添加 Add Java JDK和Add Intellij PlantForm Plugin SDK,Java JDK为java11的安装目录,Plugin SDK为 IDEA Community 2021.3.3的安装目录。 +![](../../figures/IntelliJ_env_config_SDKs.png) + +8.若完成步骤7配置,点击OK完成配置。Rebuild项目,若IDEA依然不能点击右上角的运行。请重新配置一次Modules。 + +9.项目运行成功后,会另起一个IDEA应用程序。插件运行在IDEA中,只需要新建一个Grandle Project,添加相应的TS文件到项目文件夹里面,就可以右击文件,选择Generate napi Frame出现插件主界面进行相应操作。 + +10.在Deveco stdio中安装插件。 +请在IDEA Community中依次点击Build>Prepare Plugin Module " " for development"生成jar包(jar一般生成在generator目录下)。打开DevEco Studio 工具,点击File>settings>plugin。点击右方齿轮选择install plugin from disk选择jar包,点击确定完成。重新IDE完成安装 +![](../../figures/IntelliJ_env_deveco_install.png) \ No newline at end of file diff --git a/src/generator/src/com/sk/action/BrowseAction.java b/src/generator/src/com/sk/action/BrowseAction.java index 7c573adbcb6a321a826722e886b8258f2bead19f..8554c3fe47819b8f8499b3b7d65707baef439eef 100644 --- a/src/generator/src/com/sk/action/BrowseAction.java +++ b/src/generator/src/com/sk/action/BrowseAction.java @@ -18,12 +18,15 @@ import com.intellij.notification.NotificationType; import com.intellij.openapi.project.Project; import com.sk.utils.FileUtil; import com.sk.utils.GenNotification; +import org.apache.http.util.TextUtils; + import javax.swing.JButton; import javax.swing.JTextField; import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.File; import java.util.prefs.Preferences; /** @@ -49,42 +52,86 @@ public class BrowseAction implements ActionListener { this.interField = interField; this.genField = geField; this.scriptField = scriptField; + } + @Override public void actionPerformed(ActionEvent actionEvent) { if (actionEvent.getSource().equals(button)) { Preferences preferences = Preferences.userRoot(); + JFileChooser fcDlg = new JFileChooser(); + // 获取上次打开文件的路径。 - JFileChooser fcDlg = new JFileChooser(); String pathRecord = preferences.get("interPathRecord", ""); if (!pathRecord.equals("")) { fcDlg = new JFileChooser(pathRecord); } fcDlg.setDialogTitle("请选择接口文件..."); - fcDlg.setFileSelectionMode(JFileChooser.FILES_ONLY); + fcDlg.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); FileNameExtensionFilter filter = new FileNameExtensionFilter("文本文件(*.ts)", "ts"); + fcDlg.setMultiSelectionEnabled(true); fcDlg.setFileFilter(filter); int returnVal = fcDlg.showOpenDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { - String filepath = fcDlg.getSelectedFile().getPath(); - String filename = fcDlg.getSelectedFile().getName(); + String upPath = fcDlg.getSelectedFile().getParent(); + File[] files = fcDlg.getSelectedFiles(); - if (!FileUtil.patternFileName(filename)) { - GenNotification.notifyMessage(project, - "当前文件名不符合转换规则!", - "提示", - NotificationType.WARNING); + String interFile = setSelectFile(files); + + if (TextUtils.isBlank(interFile)) { return; } - String upPath = fcDlg.getSelectedFile().getParent(); - preferences.put("interPathRecord", filepath); - interField.setText(filepath); + + // 设置默认打开路径; + + preferences.put("interPathRecord", upPath); + interField.setText(interFile.substring(0, interFile.length() - 1)); genField.setText(upPath); scriptField.setText(upPath); } } } + + private String setSelectFile(File[] files) { + String interFile = ""; + boolean existFile = false; + boolean existDir = false; + for (File file : files) { + if (file.isDirectory()) { + if (!existDir) { + existDir = true; + interFile += file.getPath() + ","; + } else { + GenNotification.notifyMessage(project, + "目前只支持单个文件夹转换", + "选择不符合要求", + NotificationType.WARNING); + interField.setText(""); + return ""; + } + } else { + if (!FileUtil.patternFileName(file.getName())) { + GenNotification.notifyMessage(project, + file.getPath(), + file.getName() + "文件名不符合", + NotificationType.WARNING); + return ""; + } + existFile = true; + interFile += file.getPath() + ","; + } + } + if (existDir && existFile) { + GenNotification.notifyMessage(project, + "不能同时转换文件和文件夹", + "选择不符合要求", + NotificationType.WARNING); + interField.setText(""); + return ""; + } + return interFile; + } } diff --git a/src/generator/src/com/sk/dialog/GenerateDialog.java b/src/generator/src/com/sk/dialog/GenerateDialog.java index 8bd9db76e12d2ddc5028402ff08fe14f3364e48d..54053098c8bc4f3b82f2bb602338f8a97cb69fef 100644 --- a/src/generator/src/com/sk/dialog/GenerateDialog.java +++ b/src/generator/src/com/sk/dialog/GenerateDialog.java @@ -84,7 +84,6 @@ public class GenerateDialog extends DialogWrapper { @Nullable @Override protected ValidationInfo doValidate() { - return genDiag.validationInfo(); } @@ -128,6 +127,7 @@ public class GenerateDialog extends DialogWrapper { if (validationInfo != null) { LOG.info(validationInfo.message); } else { + if (genDiag.runFun()) { close(CANCEL_EXIT_CODE); } diff --git a/src/generator/src/com/sk/dialog/GenerateDialogPane.form b/src/generator/src/com/sk/dialog/GenerateDialogPane.form index 8c23604dbf4f3ad3c8961566d97e54b8d2925a0a..f846b03becbc326490a985d9599b23fcd96e745b 100644 --- a/src/generator/src/com/sk/dialog/GenerateDialogPane.form +++ b/src/generator/src/com/sk/dialog/GenerateDialogPane.form @@ -26,6 +26,7 @@ + @@ -56,6 +57,7 @@ + @@ -88,6 +90,7 @@ + diff --git a/src/generator/src/com/sk/dialog/GenerateDialogPane.java b/src/generator/src/com/sk/dialog/GenerateDialogPane.java index a498af34535afba0b917d25bdff29e0998d70cd3..f1642948a75a89da2160f19ae004100dc8095b7b 100644 --- a/src/generator/src/com/sk/dialog/GenerateDialogPane.java +++ b/src/generator/src/com/sk/dialog/GenerateDialogPane.java @@ -24,6 +24,8 @@ import com.sk.action.ScriptAction; import com.sk.utils.FileUtil; import com.sk.utils.GenNotification; import org.apache.http.util.TextUtils; +import org.jetbrains.annotations.Nullable; + import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JPanel; @@ -76,9 +78,11 @@ public class GenerateDialogPane extends JDialog { private String fileName; private Project project; + /** * 构造函数 - * @param project projectid + * + * @param project projectid * @param interFilePath 接口文件路径 * @param genDir 生成框架文件路径 * @param scriptDir 脚本目录 @@ -101,7 +105,8 @@ public class GenerateDialogPane extends JDialog { contentPane.registerKeyboardAction(actionEvent -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); - selectInter.addActionListener(new BrowseAction(project, selectInter, interPath, genPath, scriptPath)); + BrowseAction browseAction = new BrowseAction(project, selectInter, interPath, genPath, scriptPath); + selectInter.addActionListener(browseAction); selectGenPath.addActionListener(new GenAction(selectGenPath, genPath)); selectScriptPath.addActionListener(new ScriptAction(selectScriptPath, scriptPath)); } @@ -127,6 +132,7 @@ public class GenerateDialogPane extends JDialog { * * @return ValidationInfo 返回不符要求的信息。 */ + @Nullable public ValidationInfo validationInfo() { String fileInter = interPath.getText(); String scriptDir = scriptPath.getText(); @@ -135,7 +141,7 @@ public class GenerateDialogPane extends JDialog { || TextUtils.isEmpty(scriptDir) || TextUtils.isEmpty(filegypDir); - ValidationInfo validationInfo = new ValidationInfo(null); + ValidationInfo validationInfo = null; if (isEmptyFile) { String warnMsg = "接口文件、框架、编译脚本路径不能为空"; warningMessage("Please input interface,gen and gyp file directory", warnMsg); @@ -199,8 +205,6 @@ public class GenerateDialogPane extends JDialog { String sysName = System.getProperties().getProperty("os.name").toUpperCase(); String tmpDirFile = System.getProperty("java.io.tmpdir"); String execFn; - - if (sysName.indexOf("WIN") >= 0) { execFn = "cmds/win/napi_generator-win.exe"; tmpDirFile += "napi_generator-win.exe"; @@ -211,13 +215,11 @@ public class GenerateDialogPane extends JDialog { execFn = "cmds/mac/napi_generator-macos"; tmpDirFile += "napi_generator-macos"; } - ; - File file = new File(tmpDirFile); if (!file.exists()) { try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(execFn)) { if (inputStream == null) { - return ""; + throw new IOException("exec File InputStream is Null"); } byte[] bs = inputStream.readAllBytes(); writeTmpFile(tmpDirFile, bs); @@ -231,7 +233,44 @@ public class GenerateDialogPane extends JDialog { return ""; } } - return file + " " + "-f" + " " + destPath + " " + "-o" + " " + parentPath; + + String command = file.toString(); + String inArgs = genInArgs(destPath); + command += inArgs + " -o " + parentPath; + return command; + } + + /** + * 生成 -f -d 输入参数。 + * + * @param destPath 源文件路径。 + * @return 生成后的值-f -d的值 + */ + private String genInArgs(String destPath) { + + String[] interArr = destPath.split(","); + String tsParam = " -f "; + String dirParam = " -d "; + String inputCommand = ""; + if (interArr.length > 0) { + for (String interStr : interArr) { + File interFile = new File(interStr); + if (interFile.isDirectory()) { + dirParam += interStr + " "; + } else { + tsParam += interStr + ","; + } + } + if (!TextUtils.isEmpty(tsParam.replaceAll("-f", "")) + && !TextUtils.isBlank(tsParam.replaceAll("-f", ""))) { + inputCommand += tsParam.substring(0, tsParam.length() - 1); + } + if (!TextUtils.isEmpty(dirParam.replace("-d", "")) + && !TextUtils.isBlank(dirParam.replace("-d", ""))) { + inputCommand += dirParam.substring(0, dirParam.length() - 1); + } + } + return inputCommand; } private boolean callExtProcess(String command) throws IOException, InterruptedException { @@ -263,7 +302,7 @@ public class GenerateDialogPane extends JDialog { /** * 写makeFile.txt文件 * - * @throws IOException 文件异常 + * @throws IOException 文件异常 */ private void writeCommand() { FileUtil fileUtil = new FileUtil(); @@ -287,7 +326,7 @@ public class GenerateDialogPane extends JDialog { * 赋值可执行文件权限。 * * @param execFn 可执行命令 - * @throws IOException 打开文件异常 + * @throws IOException 打开文件异常 * @throws InterruptedException 中断异常 */ private void executable(String execFn) throws IOException, InterruptedException { diff --git a/src/generator/src/com/sk/utils/FileUtil.java b/src/generator/src/com/sk/utils/FileUtil.java index e3ff8bc70df7a2c074564d9eeda302bdcc70d571..f4f69acc10191109e4ab08145dce2a05fe53817c 100644 --- a/src/generator/src/com/sk/utils/FileUtil.java +++ b/src/generator/src/com/sk/utils/FileUtil.java @@ -18,6 +18,7 @@ import com.intellij.notification.NotificationType; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import org.apache.commons.lang3.StringUtils; +import org.apache.http.util.TextUtils; import java.io.BufferedReader; import java.io.File; @@ -93,7 +94,7 @@ public class FileUtil { File file = new File(path); String[] command = content.split(StringUtils.LF); try (InputStreamReader read = new InputStreamReader(new FileInputStream(file), "UTF-8"); - BufferedReader bufferedReader = new BufferedReader(read)) { + BufferedReader bufferedReader = new BufferedReader(read)) { return isContainString(bufferedReader, command); } } @@ -144,7 +145,7 @@ public class FileUtil { /** * check project SDK * - * @param project projectid + * @param project projectid * @param baseFile project root file * @return boolean */ @@ -155,13 +156,19 @@ public class FileUtil { if (baseDir.isDirectory()) { File[] childFile = baseDir.listFiles(); for (File file : childFile) { - if (file.getName().equals("build.gradle")) { + if (file.getName().equals("build.gradle") || file.getName().equals("build-profile.json5")) { gradlePath = file.getPath(); } } } Properties properties = new Properties(); + if (TextUtils.isBlank(gradlePath)) { + GenNotification.notifyMessage(project, "项目结构中没有grandle配置文件。", + "当前项目结构不支持", + NotificationType.WARNING); + return false; + } try { properties.load(new FileInputStream(gradlePath)); } catch (IOException e) {