diff --git a/.gitignore b/.gitignore index 1557c64c..defebe3d 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ /src/generator/resources/cmds/mac/napi_generator-macos /src/generator/resources/cmds/win/napi_generator-win.exe /src/generator/.idea/ +/src/package-lock.json +/src/package.json diff --git a/figures/IntelliJ_env_config_SDKs.png b/figures/IntelliJ_env_config_SDKs.png new file mode 100644 index 00000000..0d88eb74 Binary files /dev/null and b/figures/IntelliJ_env_config_SDKs.png differ diff --git a/figures/IntelliJ_env_deveco_install.png b/figures/IntelliJ_env_deveco_install.png new file mode 100644 index 00000000..17cb2a81 Binary files /dev/null and b/figures/IntelliJ_env_deveco_install.png differ diff --git a/src/generator/README_zh.md b/src/generator/README_zh.md index a1eea01f..a3202496 100644 --- a/src/generator/README_zh.md +++ b/src/generator/README_zh.md @@ -1,7 +1,7 @@ # IDEA插件开发环境配置 基础环境要求: -JDK 11 ,IDEA Community 213及以上 +JDK 11 ,IDEA Community 2021.3.3 1.下载IDEA Community 与 JDK11 配置好环境 点击 https://www.jetbrains.com/idea/download/ 下载Community版本,并完成安装。 @@ -15,14 +15,28 @@ JDK 11 ,IDEA Community 213及以上 项目打开完成,点击File>Project Structure ![](../../figures/IntelliJ_env_proj_structure.png) + 4.配置Modules. -Project Settings > Modules 新建Modules,再new Modules界面选择IntelliJ Platform Plugin。点击上方“-”删除原有的Modules,点击上方侧“+”选择 New 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) \ No newline at end of file +![](../../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 7c573adb..8554c3fe 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(); + + // 获取上次打开文件的路径。 + 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 8bd9db76..54053098 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 8c23604d..f846b03b 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 a498af34..f1642948 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 e3ff8bc7..f4f69acc 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) {