Skip to content

Commit c5b7a99

Browse files
committed
Fix the issue of getting the default README.md file content of repos tree.
1 parent 7eb9d6b commit c5b7a99

File tree

3 files changed

+98
-60
lines changed

3 files changed

+98
-60
lines changed

api-doc/repos.http

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,19 @@ Content-Type: {{contentType}}
4848
# @apiParam {String} [recursive] 用于获取递归树的布尔值(默认为false)
4949

5050
GET {{baseUrl}}/api/repos/{{id}}/tree
51-
Content-Type: {{contentType}}
51+
Content-Type: {{contentType}}
52+
53+
# @apiSuccess {String} readmeContent 返回 README.md 内容
54+
# @apiSuccess sha 7eb9d6bbf8ef2f3236f0e71dd8e020715507ea01
55+
# @apiSuccess summary 提交commit内容 "Add repo tree API parameter path."
56+
# @apiSuccess message 提交commit内容 "Add repo tree API parameter path.\n"
57+
# @apiSuccess messageRaw 提交commit内容 "Add repo tree API parameter path.\n"
58+
# @apiSuccess owner 返回 { "name": "jaywcjlove", "email": "398188662@qq.com" }
59+
# @apiSuccess amend
60+
# @apiSuccess time 535736727
61+
# @apiSuccess date 2018-08-31T17:32:07.000Z"
62+
# @apiSuccess timeMs 535736727000
63+
# @apiSuccess timeOffset 80
64+
# @apiSuccess isFile alse
65+
# @apiSuccess path 返回路径
66+
# @apiSuccess entryCount

src/controller/git/repos/index.js

Lines changed: 46 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,7 @@ const FS = require('fs-extra')
44
const Models = require('../../../../conf/sequelize');
55
const { readFile } = require('../../../utils/fsExtra');
66

7-
/**
8-
* 获取目录
9-
* @param {Object} treeWalker
10-
* @param {Boolean} [recursive=false] 以广度优先顺序递归地遍历树。
11-
*/
12-
const getFiles = (treeWalker, recursive = false) => {
13-
const trees = [];
14-
return new Promise((resolve, reject) => {
15-
treeWalker.on("entry", (entry) => {
16-
let type = '';
17-
if (entry.isBlob()) type = 'blob';
18-
if (entry.isDirectory()) type = 'tree';
19-
if (entry.isSubmodule()) type = 'commit';
20-
trees.push({
21-
id: entry.sha(),
22-
name: entry.name(),
23-
path: entry.path(),
24-
filemodeRaw: entry.filemodeRaw(),
25-
mode: entry.filemode(),
26-
type,
27-
});
28-
});
29-
treeWalker.on("end", (entries) => {
30-
if (recursive) resolve(trees);
31-
});
32-
treeWalker.on("error", (error) => {
33-
reject(error)
34-
});
35-
treeWalker.start();
36-
if (!recursive) resolve(trees);
37-
});
38-
}
7+
const { getFiles } = require('./util');
398

409
module.exports = {
4110
created: async (ctx) => {
@@ -134,23 +103,9 @@ module.exports = {
134103
readme: async (ctx) => {
135104
const { owner, repo } = ctx.params;
136105
const { reposPath } = ctx.state.conf;
137-
const { userInfo } = ctx.session;
138106
const currentRepoPath = PATH.join(reposPath, owner, `${repo}.git`);
139107
try {
140108
const gitRepo = await Git.Repository.open(currentRepoPath);
141-
let emptyRepoReadme = await readFile(PATH.join(__dirname, 'EmptyRepo.md'));
142-
if (gitRepo.isEmpty() === 1) {
143-
if (userInfo.username !== owner) emptyRepoReadme = '';
144-
if (userInfo.username === owner) {
145-
emptyRepoReadme = emptyRepoReadme
146-
.replace(/\{\{username\}\}/g, owner)
147-
.replace(/\{\{repos\}\}/g, repo)
148-
.replace(/\{\{host\}\}/g, ctx.hostname)
149-
.replace(/\{\{email\}\}/g, userInfo.email)
150-
}
151-
ctx.body = { content: emptyRepoReadme };
152-
return;
153-
}
154109
let refCommit = await gitRepo.getReferenceCommit('refs/heads/master');
155110
refCommit = await gitRepo.getCommit(refCommit.sha());
156111
refCommit = await refCommit.getEntry("README.md");
@@ -163,7 +118,8 @@ module.exports = {
163118
},
164119
reposTree: async (ctx) => {
165120
const { id } = ctx.params;
166-
let { recursive = false, branch } = ctx.query;
121+
const { userInfo } = ctx.session;
122+
let { recursive = false, branch = 'master' } = ctx.query;
167123
try {
168124
const projects = await Models.projects.findOne({
169125
where: { id },
@@ -178,20 +134,30 @@ module.exports = {
178134
});
179135
if (!projects) ctx.throw(404, `Owner ${id} does not exist`);
180136

137+
const repoDetail = await Models.projects.findOne({
138+
where: { id },
139+
include: [{ model: Models.users, as: 'owner', attributes: { exclude: ['password'] } }]
140+
});
141+
181142
const { reposPath } = ctx.state.conf;
182143
const currentRepoPath = PATH.join(reposPath, projects.namespace.name, `${projects.name}.git`);
183144
const gitRepo = await Git.Repository.open(currentRepoPath);
145+
146+
// 空仓库返回 README.md 说明内容
147+
let emptyRepoReadme = await readFile(PATH.join(__dirname, 'EmptyRepo.md'));
184148
if (gitRepo.isEmpty() === 1) {
185-
ctx.body = { tree: [] };
149+
if (userInfo.username !== repoDetail.owner.username) emptyRepoReadme = '';
150+
if (userInfo.username === repoDetail.owner.username) {
151+
emptyRepoReadme = emptyRepoReadme
152+
.replace(/\{\{username\}\}/g, repoDetail.owner.username)
153+
.replace(/\{\{repos\}\}/g, repoDetail.name)
154+
.replace(/\{\{host\}\}/g, ctx.hostname)
155+
.replace(/\{\{email\}\}/g, userInfo.email)
156+
}
157+
ctx.body = { tree: [], readmeContent: emptyRepoReadme };
186158
return;
187159
}
188-
let commit;
189-
if (branch) {
190-
commit = await gitRepo.getReferenceCommit(branch);
191-
} else {
192-
commit = await gitRepo.getMasterCommit();
193-
}
194-
160+
let commit = await gitRepo.getReferenceCommit(branch);
195161
const body = {}
196162
body.sha = commit.sha();
197163
// body.toString = commit.toString();
@@ -210,22 +176,43 @@ module.exports = {
210176
body.date = commit.date();
211177
body.timeMs = commit.timeMs();
212178
body.timeOffset = commit.timeOffset();
179+
body.isFile = false;
213180

214181
// const treeId = Git.Oid.fromString('5d08433fcb6ecbfe3d1709013452f3d41ffa1ced');
215182
const treeId = Git.Oid.fromString(body.sha);
216183
commit = await commit.getTree(treeId);
217184

218185
// 参数 path 处理,存储库中的路径
219186
if (ctx.query.path) {
220-
let dirTree = await commit.getEntry(ctx.query.path);
221-
dirTree = await dirTree.getTree(dirTree.sha());
222-
commit = dirTree;
187+
let treeObj = await commit.getEntry(ctx.query.path);
188+
if (treeObj.isFile()) {
189+
body.isFile = treeObj.isFile();
190+
treeObj = await treeObj.getBlob();
191+
body.path = ctx.query.path;
192+
body.tree = [];
193+
body.readmeContent = treeObj.toString();
194+
ctx.body = body;
195+
return;
196+
}
197+
treeObj = await treeObj.getTree(treeObj.sha());
198+
commit = treeObj;
223199
}
224200

225201
body.path = commit.path();
226202
body.entryCount = commit.entryCount();
203+
body.readmeContent = ''; // 默认目录下的 README.md 文件内容为空
227204
commit = await commit.walk(recursive);
228-
body.tree = await getFiles(commit, recursive);
205+
const treeArray = await getFiles(commit, recursive);
206+
// 过滤 entry 对象
207+
const oldTree = [...treeArray].map(({ entry, ...otherProps }) => otherProps);
208+
// 读取默认目录中的 README.md 文件内容
209+
let readme = treeArray.filter(item => item.type === 'blob' && /readme.md$/.test(item.path.toLocaleLowerCase()));
210+
if (readme && readme.length > 0) {
211+
readme = readme[0];
212+
const blob = await readme.entry.getBlob();
213+
body.readmeContent = await blob.toString();
214+
}
215+
body.tree = [...oldTree];
229216
ctx.body = body;
230217
} catch (err) {
231218
ctx.response.status = err.statusCode || err.status || 500;

src/controller/git/repos/util.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Nodegit entries 获取目录
3+
* @param {Object} treeWalker
4+
* @param {Boolean} [recursive=false] 以广度优先顺序递归地遍历树。
5+
*/
6+
exports.getFiles = (treeWalker, recursive = false) => {
7+
const trees = [];
8+
return new Promise((resolve, reject) => {
9+
treeWalker.on("entry", (entry) => {
10+
let type = '';
11+
if (entry.isBlob()) type = 'blob';
12+
if (entry.isDirectory()) type = 'tree';
13+
if (entry.isSubmodule()) type = 'commit';
14+
const props = {
15+
id: entry.sha(),
16+
name: entry.name(),
17+
path: entry.path(),
18+
// filemodeRaw: entry.filemodeRaw(),
19+
mode: entry.filemode(),
20+
type,
21+
};
22+
if (/readme.md$/.test(entry.path().toLocaleLowerCase())) {
23+
props.entry = entry;
24+
}
25+
trees.push(props);
26+
});
27+
treeWalker.on("end", (entries) => {
28+
if (recursive) resolve(trees);
29+
});
30+
treeWalker.on("error", (error) => {
31+
reject(error)
32+
});
33+
treeWalker.start();
34+
if (!recursive) resolve(trees);
35+
});
36+
}

0 commit comments

Comments
 (0)