-
Notifications
You must be signed in to change notification settings - Fork 5.1k
/
add_issue.js
137 lines (119 loc) · 4.53 KB
/
add_issue.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const axios = require('axios');
const fs = require('fs').promises;
// GitHub API 配置
const API_URL = "https://api.github.com";
const REPO_OWNER = "SwiftGGTeam";
const REPO_NAME = "the-swift-programming-language-in-chinese";
const BRANCH = "swift-6-beta-translation";
// 您的个人访问令牌
const TOKEN = process.env.GITHUB_TOKEN;
// 设置请求头
const headers = {
"Authorization": `token ${TOKEN}`,
"Accept": "application/vnd.github.v3+json"
};
async function getExistingIssues() {
const issues = new Set();
let page = 1;
while (true) {
const url = `${API_URL}/repos/${REPO_OWNER}/${REPO_NAME}/issues?state=all&per_page=100&page=${page}`;
const response = await axios.get(url, { headers });
if (response.data.length === 0) break;
response.data.forEach(issue => issues.add(issue.title));
page++;
}
return issues;
}
async function createIssue(title, body, labels) {
try {
const url = `${API_URL}/repos/${REPO_OWNER}/${REPO_NAME}/issues`;
const data = { title, body, labels };
const response = await axios.post(url, data, { headers });
if (response.status === 201) {
console.log(`Issue created successfully: ${title}`);
return response.data;
} else {
console.log(`Failed to create issue: ${response.status}`);
console.log(response.data);
return null;
}
} catch (error) {
console.error("Error creating issue:", error.message);
return null;
}
}
async function getFilesInDirectory(path) {
try {
const url = `${API_URL}/repos/${REPO_OWNER}/${REPO_NAME}/contents/${path}?ref=${BRANCH}`;
const response = await axios.get(url, { headers });
if (response.status === 200) {
return response.data.filter(item => item.type === "file" && item.name.endsWith('.md'));
} else {
console.log(`Failed to get directory contents: ${response.status}`);
return [];
}
} catch (error) {
console.error("Error getting directory contents:", error.message);
return [];
}
}
function formatIssueTitle(filePath, estimatedTime) {
const parts = filePath.split('/');
const fileName = parts.pop().toLowerCase();
const folderName = parts[parts.length - 1];
// Convert camelCase or PascalCase to kebab-case
const kebabFileName = fileName
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
.replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
.toLowerCase();
return `${folderName} / ${kebabFileName} ${estimatedTime}`;
}
function formatIssueBody(filePath) {
const fileUrl = `https://github.com/${REPO_OWNER}/${REPO_NAME}/blob/${BRANCH}/${filePath}`;
return `翻译文件:${fileUrl}\n请在认领任务前查看 Markdown 文件内容,并了解对应的 Swift 原文档链接和翻译预估时长`;
}
async function getFileContent(filePath) {
try {
const url = `${API_URL}/repos/${REPO_OWNER}/${REPO_NAME}/contents/${filePath}?ref=${BRANCH}`;
const response = await axios.get(url, { headers });
if (response.status === 200) {
return Buffer.from(response.data.content, 'base64').toString('utf-8');
}
} catch (error) {
console.error(`Error getting file content: ${error.message}`);
}
return null;
}
function extractEstimatedTime(content) {
const match = content.match(/翻译估计用时:(.*)/);
return match ? match[1].trim() : '';
}
async function processDirectory(path, existingIssues) {
const files = await getFilesInDirectory(path);
for (const file of files) {
const content = await getFileContent(file.path);
if (content) {
const estimatedTime = extractEstimatedTime(content);
const issueTitle = formatIssueTitle(file.path, estimatedTime);
if (!existingIssues.has(issueTitle)) {
const issueBody = formatIssueBody(file.path);
await createIssue(issueTitle, issueBody, ["Swift 6 beta translation"]);
} else {
console.log(`Issue already exists: ${issueTitle}`);
}
}
}
}
async function main() {
const existingIssues = await getExistingIssues();
console.log(`Found ${existingIssues.size} existing issues.`);
const directories = [
"swift-6.docc/GuidedTour",
"swift-6.docc/LanguageGuide",
"swift-6.docc/ReferenceManual"
];
for (const dir of directories) {
await processDirectory(dir, existingIssues);
}
}
main().catch(console.error);