Commit b5821b4bef4925c504d23dd723f9ab604a9a2762
Committed by
Gitee
!132 优化一键改包的实现,增强对 win 的兼容性
Merge pull request !132 from 芋道源码/feature/project-reactor
Showing
1 changed file
with
65 additions
and
19 deletions
yudao-server/src/test/java/cn/iocoder/yudao/ProjectReactor.java
| 1 | package cn.iocoder.yudao; | 1 | package cn.iocoder.yudao; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.io.FileTypeUtil; | ||
| 3 | import cn.hutool.core.io.FileUtil; | 4 | import cn.hutool.core.io.FileUtil; |
| 4 | import cn.hutool.core.util.StrUtil; | 5 | import cn.hutool.core.util.StrUtil; |
| 6 | +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | ||
| 5 | import lombok.extern.slf4j.Slf4j; | 7 | import lombok.extern.slf4j.Slf4j; |
| 6 | import org.apache.commons.io.FileUtils; | 8 | import org.apache.commons.io.FileUtils; |
| 7 | 9 | ||
| 8 | import java.io.File; | 10 | import java.io.File; |
| 9 | import java.nio.charset.StandardCharsets; | 11 | import java.nio.charset.StandardCharsets; |
| 10 | import java.util.Collection; | 12 | import java.util.Collection; |
| 13 | +import java.util.Set; | ||
| 14 | +import java.util.regex.Matcher; | ||
| 15 | +import java.util.stream.Collectors; | ||
| 16 | + | ||
| 17 | +import static java.io.File.separator; | ||
| 11 | 18 | ||
| 12 | /** | 19 | /** |
| 13 | * 项目修改器,一键替换 Maven 的 groupId、artifactId,项目的 package 等 | 20 | * 项目修改器,一键替换 Maven 的 groupId、artifactId,项目的 package 等 |
| 14 | - * | 21 | + * <p> |
| 15 | * 通过修改 groupIdNew、artifactIdNew、projectBaseDirNew 三个变量 | 22 | * 通过修改 groupIdNew、artifactIdNew、projectBaseDirNew 三个变量 |
| 16 | * | 23 | * |
| 17 | * @author 芋道源码 | 24 | * @author 芋道源码 |
| @@ -24,8 +31,16 @@ public class ProjectReactor { | @@ -24,8 +31,16 @@ public class ProjectReactor { | ||
| 24 | private static final String PACKAGE_NAME = "cn.iocoder.yudao"; | 31 | private static final String PACKAGE_NAME = "cn.iocoder.yudao"; |
| 25 | private static final String TITLE = "芋道管理系统"; | 32 | private static final String TITLE = "芋道管理系统"; |
| 26 | 33 | ||
| 34 | + /** | ||
| 35 | + * 白名单文件,不进行重写,避免出问题 | ||
| 36 | + */ | ||
| 37 | + private static final Set<String> WHITE_FILE_TYPES = SetUtils.asSet("gif", "jpg", "svg", "png", // 图片 | ||
| 38 | + "eot", "woff2", "ttf", "woff"); // 字体 | ||
| 39 | + | ||
| 27 | public static void main(String[] args) { | 40 | public static void main(String[] args) { |
| 41 | + long start = System.currentTimeMillis(); | ||
| 28 | String projectBaseDir = getProjectBaseDir(); | 42 | String projectBaseDir = getProjectBaseDir(); |
| 43 | + log.info("[main][原项目路劲改地址 ({})]", projectBaseDir); | ||
| 29 | 44 | ||
| 30 | // ========== 配置,需要你手动修改 ========== | 45 | // ========== 配置,需要你手动修改 ========== |
| 31 | String groupIdNew = "cn.star.gg"; | 46 | String groupIdNew = "cn.star.gg"; |
| @@ -33,41 +48,61 @@ public class ProjectReactor { | @@ -33,41 +48,61 @@ public class ProjectReactor { | ||
| 33 | String packageNameNew = "cn.start.pp"; | 48 | String packageNameNew = "cn.start.pp"; |
| 34 | String titleNew = "土豆管理系统"; | 49 | String titleNew = "土豆管理系统"; |
| 35 | String projectBaseDirNew = projectBaseDir + "-new"; // 一键改名后,“新”项目所在的目录 | 50 | String projectBaseDirNew = projectBaseDir + "-new"; // 一键改名后,“新”项目所在的目录 |
| 36 | - // ========== ========== | 51 | + log.info("[main][新项目路径地址 ({})]", projectBaseDirNew); |
| 37 | 52 | ||
| 38 | // 获得需要复制的文件 | 53 | // 获得需要复制的文件 |
| 39 | - log.info("[main][开始获得需要重写的文件]"); | 54 | + log.info("[main][开始获得需要重写的文件,预计需要 10-20 秒]"); |
| 40 | Collection<File> files = listFiles(projectBaseDir); | 55 | Collection<File> files = listFiles(projectBaseDir); |
| 41 | - log.info("[main][需要重写的文件数量:{},预计需要 5-10 秒]", files.size()); | 56 | + log.info("[main][需要重写的文件数量:{},预计需要 15-30 秒]", files.size()); |
| 42 | // 写入文件 | 57 | // 写入文件 |
| 43 | files.forEach(file -> { | 58 | files.forEach(file -> { |
| 59 | + // 如果是白名单的文件类型,不进行重写,直接拷贝 | ||
| 60 | + String fileType = FileTypeUtil.getType(file); | ||
| 61 | + if (WHITE_FILE_TYPES.contains(fileType)) { | ||
| 62 | + copyFile(file, projectBaseDir, projectBaseDirNew, packageNameNew, artifactIdNew); | ||
| 63 | + return; | ||
| 64 | + } | ||
| 65 | + // 如果非白名单的文件类型,重写内容,在生成文件 | ||
| 44 | String content = replaceFileContent(file, groupIdNew, artifactIdNew, packageNameNew, titleNew); | 66 | String content = replaceFileContent(file, groupIdNew, artifactIdNew, packageNameNew, titleNew); |
| 45 | writeFile(file, content, projectBaseDir, projectBaseDirNew, packageNameNew, artifactIdNew); | 67 | writeFile(file, content, projectBaseDir, projectBaseDirNew, packageNameNew, artifactIdNew); |
| 46 | }); | 68 | }); |
| 47 | - log.info("[main][重写完成]"); | 69 | + log.info("[main][重写完成]共耗时:{} 秒", (System.currentTimeMillis() - start) / 1000); |
| 48 | } | 70 | } |
| 49 | 71 | ||
| 50 | private static String getProjectBaseDir() { | 72 | private static String getProjectBaseDir() { |
| 51 | - // noinspection ConstantConditions | ||
| 52 | - return StrUtil.subBefore(ProjectReactor.class.getClassLoader().getResource("").getFile(), | ||
| 53 | - "/yudao-server", false); | 73 | + String baseDir = System.getProperty("user.dir"); |
| 74 | + if (StrUtil.isEmpty(baseDir)) { | ||
| 75 | + throw new NullPointerException("项目基础路径不存在"); | ||
| 76 | + } | ||
| 77 | + return baseDir; | ||
| 54 | } | 78 | } |
| 55 | 79 | ||
| 56 | private static Collection<File> listFiles(String projectBaseDir) { | 80 | private static Collection<File> listFiles(String projectBaseDir) { |
| 57 | Collection<File> files = FileUtils.listFiles(new File(projectBaseDir), null, true); | 81 | Collection<File> files = FileUtils.listFiles(new File(projectBaseDir), null, true); |
| 58 | - files.removeIf(file -> file.getPath().contains("/target/")); | ||
| 59 | - files.removeIf(file -> file.getPath().contains("/node_modules/")); | ||
| 60 | - files.removeIf(file -> file.getPath().contains("/.idea/")); // 移除 IDEA 自身的文件 | ||
| 61 | - files.removeIf(file -> file.getPath().contains("/.git/")); // 移除 Git 自身的文件 | ||
| 62 | - files.removeIf(file -> file.getPath().contains("/dist/")); // 移除 Node 编译出来的 | 82 | + // 移除 IDEA、Git 自身的文件、Node 编译出来的文件 |
| 83 | + files = files.stream() | ||
| 84 | + .filter(file -> !file.getPath().contains(separator + "target" + separator) | ||
| 85 | + && !file.getPath().contains(separator + "node_modules" + separator) | ||
| 86 | + && !file.getPath().contains(separator + ".idea" + separator) | ||
| 87 | + && !file.getPath().contains(separator + ".git" + separator) | ||
| 88 | + && !file.getPath().contains(separator + "dist" + separator) | ||
| 89 | + && !file.getPath().contains(".iml") | ||
| 90 | + && !file.getPath().contains(".html.gz")) | ||
| 91 | + .collect(Collectors.toList()); | ||
| 63 | return files; | 92 | return files; |
| 64 | } | 93 | } |
| 65 | 94 | ||
| 66 | private static String replaceFileContent(File file, String groupIdNew, | 95 | private static String replaceFileContent(File file, String groupIdNew, |
| 67 | String artifactIdNew, String packageNameNew, | 96 | String artifactIdNew, String packageNameNew, |
| 68 | String titleNew) { | 97 | String titleNew) { |
| 69 | - return FileUtil.readString(file, StandardCharsets.UTF_8) | ||
| 70 | - .replaceAll(GROUP_ID, groupIdNew) | 98 | + String content = FileUtil.readString(file, StandardCharsets.UTF_8); |
| 99 | + // 如果是白名单的文件类型,不进行重写 | ||
| 100 | + String fileType = FileTypeUtil.getType(file); | ||
| 101 | + if (WHITE_FILE_TYPES.contains(fileType)) { | ||
| 102 | + return content; | ||
| 103 | + } | ||
| 104 | + // 执行文件内容都重写 | ||
| 105 | + return content.replaceAll(GROUP_ID, groupIdNew) | ||
| 71 | .replaceAll(PACKAGE_NAME, packageNameNew) | 106 | .replaceAll(PACKAGE_NAME, packageNameNew) |
| 72 | .replaceAll(ARTIFACT_ID, artifactIdNew) // 必须放在最后替换,因为 ARTIFACT_ID 太短! | 107 | .replaceAll(ARTIFACT_ID, artifactIdNew) // 必须放在最后替换,因为 ARTIFACT_ID 太短! |
| 73 | .replaceAll(StrUtil.upperFirst(ARTIFACT_ID), StrUtil.upperFirst(artifactIdNew)) | 108 | .replaceAll(StrUtil.upperFirst(ARTIFACT_ID), StrUtil.upperFirst(artifactIdNew)) |
| @@ -76,12 +111,23 @@ public class ProjectReactor { | @@ -76,12 +111,23 @@ public class ProjectReactor { | ||
| 76 | 111 | ||
| 77 | private static void writeFile(File file, String fileContent, String projectBaseDir, | 112 | private static void writeFile(File file, String fileContent, String projectBaseDir, |
| 78 | String projectBaseDirNew, String packageNameNew, String artifactIdNew) { | 113 | String projectBaseDirNew, String packageNameNew, String artifactIdNew) { |
| 79 | - String newPath = file.getPath().replace(projectBaseDir, projectBaseDirNew) // 新目录 | ||
| 80 | - .replace(PACKAGE_NAME.replaceAll("\\.", File.separator), | ||
| 81 | - packageNameNew.replaceAll("\\.", File.separator)) | 114 | + String newPath = buildNewFilePath(file, projectBaseDir, projectBaseDirNew, packageNameNew, artifactIdNew); |
| 115 | + FileUtil.writeUtf8String(fileContent, newPath); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + private static void copyFile(File file, String projectBaseDir, | ||
| 119 | + String projectBaseDirNew, String packageNameNew, String artifactIdNew) { | ||
| 120 | + String newPath = buildNewFilePath(file, projectBaseDir, projectBaseDirNew, packageNameNew, artifactIdNew); | ||
| 121 | + FileUtil.copyFile(file, new File(newPath)); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + private static String buildNewFilePath(File file, String projectBaseDir, | ||
| 125 | + String projectBaseDirNew, String packageNameNew, String artifactIdNew) { | ||
| 126 | + return file.getPath().replace(projectBaseDir, projectBaseDirNew) // 新目录 | ||
| 127 | + .replace(PACKAGE_NAME.replaceAll("\\.", Matcher.quoteReplacement(separator)), | ||
| 128 | + packageNameNew.replaceAll("\\.", Matcher.quoteReplacement(separator))) | ||
| 82 | .replace(ARTIFACT_ID, artifactIdNew) // | 129 | .replace(ARTIFACT_ID, artifactIdNew) // |
| 83 | .replaceAll(StrUtil.upperFirst(ARTIFACT_ID), StrUtil.upperFirst(artifactIdNew)); | 130 | .replaceAll(StrUtil.upperFirst(ARTIFACT_ID), StrUtil.upperFirst(artifactIdNew)); |
| 84 | - FileUtil.writeUtf8String(fileContent, newPath); | ||
| 85 | } | 131 | } |
| 86 | 132 | ||
| 87 | } | 133 | } |