UpdateGitRep.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. const fs = require("fs");
  2. const path = require("path");
  3. const child_process = require("child_process");
  4. let totalGitRepPath = new Set();
  5. const InputRepURLJsonName = "RepUrls.json";
  6. const PluginDirName = "Plugins";
  7. const dirNameBlackList = [
  8. "node_modules",
  9. "dist",
  10. "Build",
  11. "Content",
  12. "Binaries",
  13. "Config",
  14. "DerivedDataCache",
  15. "Intermediate",
  16. "pipeline",
  17. "Saved",
  18. ".vs",
  19. "ThirdParty",
  20. ]
  21. class RepUrls{
  22. repUrls = [];
  23. }
  24. // 拉取 Git 仓库最新代码到指定路径
  25. function pullGitRepository(repositoryUrl, localPath) {
  26. if (fs.existsSync(localPath)) {
  27. // 路径已存在则拉取最新代码
  28. console.log(`Pull ${repositoryUrl} to ${localPath}...`);
  29. if(!checkEditFileRep(localPath)) {
  30. return;
  31. }
  32. child_process.exec("git pull", localPath, (error, stdout, stderr) => {
  33. totalGitRepPath.delete(localPath);
  34. let logContent = `update repo dir ${localPath} update log -> ${stdout.trim()}, error -> ${stderr.trim()}, remain count = ${totalGitRepPath.size}`;
  35. if (error) {
  36. console.log('\x1B[31m%s\x1B[0m', logContent);
  37. }
  38. else {
  39. console.log(logContent);
  40. }
  41. });
  42. } else {
  43. // 路径不存在则克隆仓库
  44. console.log(`Clone ${repositoryUrl} to ${localPath}...`);
  45. child_process.exec(`git clone ${repositoryUrl} ${localPath}`, (error, stdout, stderr) => {
  46. let logContent = `clone repo dir ${localPath} update log -> ${stdout.trim()}, error -> ${stderr.trim()}`;
  47. if (error) {
  48. console.log("'\x1B[31m%s\x1B[0m',", logContent);
  49. }else{
  50. console.log(logContent);
  51. }
  52. });
  53. }
  54. }
  55. // 获取路径下所有文件夹
  56. function getAllChildrenDir(inPath)
  57. {
  58. if(inPath === undefined || inPath === null || !fs.existsSync(inPath)) {
  59. return [];
  60. }
  61. return fs.readdirSync(inPath, { withFileTypes: true }).filter(dirent => dirent.isDirectory()).map(dirent => dirent.name);
  62. }
  63. // 获取路径下所有文件
  64. function getAllChildrenFile(inPath)
  65. {
  66. if(inPath === undefined || inPath === null || !fs.existsSync(inPath)) {
  67. return [];
  68. }
  69. return fs.readdirSync(inPath, { withFileTypes: true }).filter(dirent => dirent.isFile()).map(dirent => dirent.name);
  70. }
  71. // 判断是否存在被修改的文件
  72. function checkEditFileRep(inPath)
  73. {
  74. if(inPath === undefined || inPath === null || !fs.existsSync(inPath)) {
  75. return false;
  76. }
  77. try {
  78. // `git -C "${inPath}" status --porcelain`,
  79. const output = child_process.execSync(
  80. `git -C "${inPath}" diff --name-only`,
  81. { encoding: 'utf-8' }
  82. );
  83. if(output.trim().length > 0)
  84. {
  85. console.log("'\x1B[31m%s\x1B[0m',", `${inPath} 存在被修改的文件 无法更新 使用 git restore 还原文件: ${output.trim()}`);
  86. totalGitRepPath.delete(inPath);
  87. }
  88. return output.trim().length <= 0;
  89. } catch (error) {
  90. console.error(`检查子目录失败: ${error.message}`);
  91. return false;
  92. }
  93. }
  94. function findAllGitRep(inPath)
  95. {
  96. console.log(`find path: ${inPath}`);
  97. let childrenDirs = getAllChildrenDir(inPath);
  98. if(childrenDirs.indexOf(".git") !== -1) {
  99. // 如果当前目录下有 .git 目录,则认为是一个 Git 仓库
  100. totalGitRepPath.add(inPath);
  101. }
  102. childrenDirs.forEach((dir) => {
  103. if(!dir || dir.trim().startsWith(".") || dirNameBlackList.includes(dir.trim())) {
  104. // 跳过隐藏目录
  105. return;
  106. }
  107. // console.log(`Checking directory: ${dir} in ${inPath}`);
  108. let childPath = path.join(inPath, dir);
  109. findAllGitRep(childPath);
  110. });
  111. }
  112. function updateAllRep(allPath)
  113. {
  114. allPath.forEach((inPath) => {
  115. if(inPath === undefined)
  116. {
  117. return;
  118. }
  119. pullGitRepository("", inPath);
  120. });
  121. }
  122. function updateRep()
  123. {
  124. let rootPath = __dirname;
  125. findAllGitRep(rootPath);
  126. updateAllRep(totalGitRepPath);
  127. }
  128. function cloneRep()
  129. {
  130. let rootPath = __dirname;
  131. let inputRepURLJsonFile = path.join(rootPath, InputRepURLJsonName);
  132. if(!fs.existsSync(inputRepURLJsonFile)) {
  133. let temp = new RepUrls();
  134. temp.repUrls = ["https://xxx.com/test/url.git"];
  135. fs.writeFileSync(inputRepURLJsonFile, JSON.stringify(temp, null, 4), "utf-8");
  136. console.error(`找不到 ${InputRepURLJsonName} 文件,已生成该文件,请填充内容`);
  137. return;
  138. }
  139. let repUrls = JSON.parse(fs.readFileSync(inputRepURLJsonFile, "utf-8"));
  140. repUrls.repUrls.forEach((url) => {
  141. if(!url || url.trim() === "") {
  142. console.error(`无效的 Git 仓库 URL: ${url}`);
  143. return;
  144. }
  145. let locationPath = path.join(rootPath, PluginDirName);
  146. let localPath = path.join(locationPath, path.basename(url, ".git"));
  147. pullGitRepository(url, localPath);
  148. });
  149. }
  150. function main()
  151. {
  152. if(process.argv.length < 3) {
  153. console.log("请输入 clone 或者 update 来选择下载或更新 Git 仓库");
  154. return;
  155. }
  156. let param = process.argv[2].toLowerCase();
  157. if(param === "update") {
  158. // 更新 Git 仓库
  159. updateRep();
  160. }
  161. else if(param === "clone") {
  162. // 克隆 Git 仓库
  163. cloneRep();
  164. }
  165. else {
  166. console.error(`无效的参数 "${param}",请输入 clone 或 update`);
  167. return;
  168. }
  169. }
  170. main();