GetRepoLog.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. const API = require("../../lib/API")
  2. const AccessControl = require("../../lib/AccessControl")
  3. const { BaseStdResponse } = require("../../BaseStdResponse")
  4. const db = require("../../plugin/DataBase/db")
  5. const redis = require('../../plugin/DataBase/Redis')
  6. const simpleGit = require('simple-git')
  7. class GetRepoLog extends API {
  8. constructor() {
  9. super()
  10. this.setMethod("GET")
  11. this.setPath("/Repos/Log")
  12. }
  13. async onRequest(req, res) {
  14. let { uuid, session, id } = req.query
  15. if ([uuid, session, id].some(value => value === '' || value === null || value === undefined))
  16. return res.json({
  17. ...BaseStdResponse.MISSING_PARAMETER
  18. })
  19. // 检查 session
  20. if (!await AccessControl.checkSession(uuid, session))
  21. return res.status(401).json({
  22. ...BaseStdResponse.ACCESS_DENIED
  23. })
  24. let sql = 'SELECT state, path, url FROM repos WHERE create_user = ? AND id = ?'
  25. let r = await db.query(sql, [uuid, id])
  26. if (!r || r.length === 0)
  27. return res.json({
  28. ...BaseStdResponse.ERR,
  29. msg: '未找到仓库'
  30. })
  31. if (r[0].state !== 1 || !r[0].path)
  32. return res.json({
  33. ...BaseStdResponse.ERR,
  34. msg: '仓库未成功克隆!'
  35. })
  36. try {
  37. let rawLogs
  38. const redisKey = `gitLogs:${r[0].path}`
  39. const cachedLogs = await redis.get(redisKey)
  40. if (cachedLogs)
  41. rawLogs = JSON.parse(cachedLogs)
  42. else {
  43. const git = simpleGit()
  44. await git.cwd(r[0].path)
  45. rawLogs = await git.raw([
  46. "log",
  47. "--no-merges",
  48. "--pretty=format:%H|%an|%ae|%ad|%s",
  49. "--shortstat"
  50. ])
  51. redis.set(redisKey, JSON.stringify(rawLogs), {
  52. EX: 172800
  53. })
  54. }
  55. const lines = rawLogs.split("\n")
  56. const commits = []
  57. let current = null
  58. for (let i = 0; i < lines.length; i++) {
  59. const line = lines[i].trim()
  60. // 提交信息行
  61. if (line.includes("|") && !line.includes("file changed")) {
  62. const [hash, name, email, date, ...messageParts] = line.split("|")
  63. current = {
  64. hash,
  65. name,
  66. email,
  67. date,
  68. message: messageParts.join("|").trim()
  69. }
  70. commits.push(current)
  71. }
  72. }
  73. res.json({
  74. ...BaseStdResponse.OK,
  75. data: commits
  76. })
  77. } catch (err) {
  78. res.json({
  79. ...BaseStdResponse.ERR,
  80. message: "Git 日志分析失败"
  81. });
  82. }
  83. }
  84. }
  85. module.exports.GetRepoLog = GetRepoLog