mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-12 04:15:30 +00:00
113 lines
4.2 KiB
TypeScript
113 lines
4.2 KiB
TypeScript
import { Gitlab, ProjectSchema } from "@gitbeaker/rest";
|
|
import { GitLabConfig } from "./schemas/v2.js";
|
|
import { excludeArchivedRepos, excludeForkedRepos, excludeReposByName, getTokenFromConfig, marshalBool, measure } from "./utils.js";
|
|
import { createLogger } from "./logger.js";
|
|
import { AppContext, Repository } from "./types.js";
|
|
import path from 'path';
|
|
|
|
const logger = createLogger("GitLab");
|
|
|
|
export const getGitLabReposFromConfig = async (config: GitLabConfig, ctx: AppContext) => {
|
|
const token = config.token ? getTokenFromConfig(config.token, ctx) : undefined;
|
|
const api = new Gitlab({
|
|
...(config.token ? {
|
|
token,
|
|
} : {}),
|
|
...(config.url ? {
|
|
host: config.url,
|
|
} : {}),
|
|
});
|
|
|
|
let allProjects: ProjectSchema[] = [];
|
|
|
|
if (config.groups) {
|
|
const _projects = (await Promise.all(config.groups.map(async (group) => {
|
|
logger.debug(`Fetching project info for group ${group}...`);
|
|
const { durationMs, data } = await measure(() => api.Groups.allProjects(group, {
|
|
perPage: 100,
|
|
includeSubgroups: true
|
|
}));
|
|
logger.debug(`Found ${data.length} projects in group ${group} in ${durationMs}ms.`);
|
|
|
|
return data;
|
|
}))).flat();
|
|
|
|
allProjects = allProjects.concat(_projects);
|
|
}
|
|
|
|
if (config.users) {
|
|
const _projects = (await Promise.all(config.users.map(async (user) => {
|
|
logger.debug(`Fetching project info for user ${user}...`);
|
|
const { durationMs, data } = await measure(() => api.Users.allProjects(user, {
|
|
perPage: 100,
|
|
}));
|
|
logger.debug(`Found ${data.length} projects owned by user ${user} in ${durationMs}ms.`);
|
|
return data;
|
|
}))).flat();
|
|
|
|
allProjects = allProjects.concat(_projects);
|
|
}
|
|
|
|
if (config.projects) {
|
|
const _projects = await Promise.all(config.projects.map(async (project) => {
|
|
logger.debug(`Fetching project info for project ${project}...`);
|
|
const { durationMs, data } = await measure(() => api.Projects.show(project));
|
|
logger.debug(`Found project ${project} in ${durationMs}ms.`);
|
|
return data;
|
|
}));
|
|
|
|
allProjects = allProjects.concat(_projects);
|
|
}
|
|
|
|
let repos: Repository[] = allProjects
|
|
.map((project) => {
|
|
const hostname = config.url ? new URL(config.url).hostname : "gitlab.com";
|
|
const repoId = `${hostname}/${project.path_with_namespace}`;
|
|
const repoPath = path.resolve(path.join(ctx.reposPath, `${repoId}.git`))
|
|
const isFork = project.forked_from_project !== undefined;
|
|
|
|
const cloneUrl = new URL(project.http_url_to_repo);
|
|
if (token) {
|
|
cloneUrl.username = 'oauth2';
|
|
cloneUrl.password = token;
|
|
}
|
|
|
|
return {
|
|
name: project.path_with_namespace,
|
|
id: repoId,
|
|
cloneUrl: cloneUrl.toString(),
|
|
path: repoPath,
|
|
isStale: false,
|
|
isFork,
|
|
isArchived: project.archived,
|
|
gitConfigMetadata: {
|
|
'zoekt.web-url-type': 'gitlab',
|
|
'zoekt.web-url': project.web_url,
|
|
'zoekt.name': repoId,
|
|
'zoekt.gitlab-stars': project.star_count?.toString() ?? '0',
|
|
'zoekt.gitlab-forks': project.forks_count?.toString() ?? '0',
|
|
'zoekt.archived': marshalBool(project.archived),
|
|
'zoekt.fork': marshalBool(isFork),
|
|
'zoekt.public': marshalBool(project.visibility === 'public'),
|
|
}
|
|
} satisfies Repository;
|
|
});
|
|
|
|
if (config.exclude) {
|
|
if (!!config.exclude.forks) {
|
|
repos = excludeForkedRepos(repos, logger);
|
|
}
|
|
|
|
if (!!config.exclude.archived) {
|
|
repos = excludeArchivedRepos(repos, logger);
|
|
}
|
|
|
|
if (config.exclude.projects) {
|
|
repos = excludeReposByName(repos, config.exclude.projects, logger);
|
|
}
|
|
}
|
|
|
|
logger.debug(`Found ${repos.length} total repositories.`);
|
|
|
|
return repos;
|
|
}
|