-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgithubProcessor.mjs
More file actions
122 lines (107 loc) · 4.02 KB
/
githubProcessor.mjs
File metadata and controls
122 lines (107 loc) · 4.02 KB
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
import { Octokit } from "@octokit/rest";
import path from "path";
import chalk from 'chalk';
let octokit;
function initializeOctokit(token) {
octokit = new Octokit({
auth: token,
log: {
debug: () => { },
info: () => { },
warn: console.warn,
error: console.error
}
});
}
async function parseGitHubUrl(url) {
const regex = /https?:\/\/github\.com\/([^\/]+)\/([^\/]+)(?:\/tree\/([^\/]+))?(?:\/(.*))?/;
const match = url.match(regex);
if (!match) {
throw new Error("Invalid GitHub URL");
}
const [, owner, repo, branch, path] = match;
let resultBranch = branch;
let resultPath = path || "";
if (!branch) {
// If no branch is specified, we need to fetch the default branch
try {
const { data: repoData } = await octokit.repos.get({ owner, repo });
resultBranch = repoData.default_branch;
console.log(chalk.blue(`No branch specified. Using default branch: ${chalk.bold(resultBranch)}`));
} catch (error) {
console.error(chalk.red("Error fetching repository information:"), error.message);
throw error;
}
}
return {
owner,
repo,
branch: resultBranch,
path: resultPath,
};
}
async function getGitHubContents(owner, repo, path, branch) {
try {
const { data } = await octokit.repos.getContent({
owner,
repo,
path,
ref: branch,
});
return data;
} catch (error) {
if (error.status === 404) {
console.error(chalk.red("Repository, branch, or path not found. Please check the URL and ensure it's correct."));
} else if (error.status === 403) {
console.error(chalk.red("API rate limit exceeded or authentication required. Try using a GitHub token."));
} else {
console.error(chalk.red("Error fetching GitHub contents:"), error.message);
}
throw error;
}
}
async function processGitHubFolder(url, skipPatterns, extensions, token) {
if (!octokit) {
initializeOctokit(token);
}
const { owner, repo, branch, path: repoPath } = await parseGitHubUrl(url);
console.log(chalk.blue(`Processing GitHub repository: ${chalk.bold(owner)}/${chalk.bold(repo)}`));
console.log(chalk.blue(`Branch: ${chalk.bold(branch)}, Path: ${chalk.bold(repoPath || 'root')}`));
const contents = await getGitHubContents(owner, repo, repoPath, branch);
const files = [];
for (const item of Array.isArray(contents) ? contents : [contents]) {
if (item.type === "file") {
if (
extensions.includes(path.extname(item.name)) &&
!skipPatterns.some(pattern => new RegExp(pattern).test(item.path))
) {
try {
process.stdout.write(chalk.yellow(`Fetching: ${item.path}\r`));
const fileContent = await octokit.request(item.download_url);
files.push({
path: item.path,
content: fileContent.data,
size: item.size,
});
process.stdout.write(chalk.green(`Fetched: ${item.path}${' '.repeat(20)}\n`));
} catch (error) {
console.error(chalk.red(`Error fetching file content for ${item.path}:`), error.message);
}
}
} else if (item.type === "dir") {
try {
const subfolderFiles = await processGitHubFolder(
`https://github.com/${owner}/${repo}/tree/${branch}/${item.path}`,
skipPatterns,
extensions,
token
);
files.push(...subfolderFiles);
} catch (error) {
console.error(chalk.red(`Error processing subfolder ${item.path}:`), error.message);
}
}
}
return files;
}
export { processGitHubFolder };