UpdateGitRep.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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. const output = child_process.execSync(
  79. `git -C "${inPath}" status --porcelain`,
  80. { encoding: 'utf-8' }
  81. );
  82. if(output.trim().length > 0)
  83. {
  84. console.log("'\x1B[31m%s\x1B[0m',", `${inPath} 存在被修改的文件 无法更新 使用 git restore 还原文件: ${output.trim()}`);
  85. totalGitRepPath.delete(inPath);
  86. }
  87. return output.trim().length <= 0;
  88. } catch (error) {
  89. console.error(`检查子目录失败: ${error.message}`);
  90. return false;
  91. }
  92. }
  93. function findAllGitRep(inPath)
  94. {
  95. console.log(`find path: ${inPath}`);
  96. let childrenDirs = getAllChildrenDir(inPath);
  97. if(childrenDirs.indexOf(".git") !== -1) {
  98. // 如果当前目录下有 .git 目录,则认为是一个 Git 仓库
  99. totalGitRepPath.add(inPath);
  100. }
  101. childrenDirs.forEach((dir) => {
  102. if(!dir || dir.trim().startsWith(".") || dirNameBlackList.includes(dir.trim())) {
  103. // 跳过隐藏目录
  104. return;
  105. }
  106. // console.log(`Checking directory: ${dir} in ${inPath}`);
  107. let childPath = path.join(inPath, dir);
  108. findAllGitRep(childPath);
  109. });
  110. }
  111. function updateAllRep(allPath)
  112. {
  113. allPath.forEach((inPath) => {
  114. if(inPath === undefined)
  115. {
  116. return;
  117. }
  118. pullGitRepository("", inPath);
  119. });
  120. }
  121. function updateRep()
  122. {
  123. let rootPath = __dirname;
  124. findAllGitRep(rootPath);
  125. updateAllRep(totalGitRepPath);
  126. }
  127. function cloneRep()
  128. {
  129. let rootPath = __dirname;
  130. let inputRepURLJsonFile = path.join(rootPath, InputRepURLJsonName);
  131. if(!fs.existsSync(inputRepURLJsonFile)) {
  132. let temp = new RepUrls();
  133. temp.repUrls = ["https://xxx.com/test/url.git"];
  134. fs.writeFileSync(inputRepURLJsonFile, JSON.stringify(temp, null, 4), "utf-8");
  135. console.error(`找不到 ${InputRepURLJsonName} 文件,已生成该文件,请填充内容`);
  136. return;
  137. }
  138. let repUrls = JSON.parse(fs.readFileSync(inputRepURLJsonFile, "utf-8"));
  139. repUrls.repUrls.forEach((url) => {
  140. if(!url || url.trim() === "") {
  141. console.error(`无效的 Git 仓库 URL: ${url}`);
  142. return;
  143. }
  144. let locationPath = path.join(rootPath, PluginDirName);
  145. let localPath = path.join(locationPath, path.basename(url, ".git"));
  146. pullGitRepository(url, localPath);
  147. });
  148. }
  149. function main()
  150. {
  151. if(process.argv.length < 3) {
  152. console.log("请输入 clone 或者 update 来选择下载或更新 Git 仓库");
  153. return;
  154. }
  155. let param = process.argv[2].toLowerCase();
  156. if(param === "update") {
  157. // 更新 Git 仓库
  158. updateRep();
  159. }
  160. else if(param === "clone") {
  161. // 克隆 Git 仓库
  162. cloneRep();
  163. }
  164. else {
  165. console.error(`无效的参数 "${param}",请输入 clone 或 update`);
  166. return;
  167. }
  168. }
  169. main();