mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-25 23:11:31 +00:00
171 lines
4.4 KiB
TypeScript
171 lines
4.4 KiB
TypeScript
import { logger } from '../../../logger/index.ts';
|
|
import * as memCache from '../../../util/cache/memory/index.ts';
|
|
import { getCache } from '../../../util/cache/repository/index.ts';
|
|
import { repoCacheProvider } from '../../../util/http/cache/repository-http-cache-provider.ts';
|
|
import type {
|
|
GitlabHttp,
|
|
GitlabHttpOptions,
|
|
} from '../../../util/http/gitlab.ts';
|
|
import { regEx } from '../../../util/regex.ts';
|
|
import { getQueryString } from '../../../util/url.ts';
|
|
import { GitLabMergeRequestsSchema } from './schema.ts';
|
|
import type { GitlabPr, GitlabPrCacheData } from './types.ts';
|
|
import { prInfo } from './utils.ts';
|
|
|
|
export class GitlabPrCache {
|
|
private items: GitlabPr[] = [];
|
|
private cache: GitlabPrCacheData;
|
|
private repo: string;
|
|
private ignorePrAuthor: boolean;
|
|
|
|
private constructor(
|
|
repo: string,
|
|
author: string | null,
|
|
ignorePrAuthor: boolean,
|
|
) {
|
|
this.repo = repo;
|
|
this.ignorePrAuthor = ignorePrAuthor;
|
|
const repoCache = getCache();
|
|
repoCache.platform ??= {};
|
|
repoCache.platform.gitlab ??= {};
|
|
|
|
let pullRequestCache = repoCache.platform.gitlab
|
|
.pullRequestsCache as GitlabPrCacheData;
|
|
if (!pullRequestCache) {
|
|
logger.debug('Initializing new PR cache at repository cache');
|
|
pullRequestCache = {
|
|
items: {},
|
|
updated_at: null,
|
|
author,
|
|
};
|
|
} else if (pullRequestCache.author !== author) {
|
|
logger.debug('Resetting PR cache because authors do not match');
|
|
pullRequestCache = {
|
|
items: {},
|
|
updated_at: null,
|
|
author,
|
|
};
|
|
} else if (pullRequestCache.updated_at?.match(regEx(/\.\d\d\dZ$/))) {
|
|
logger.debug('Resetting PR cache of older format');
|
|
pullRequestCache = {
|
|
items: {},
|
|
updated_at: null,
|
|
author,
|
|
};
|
|
}
|
|
repoCache.platform.gitlab.pullRequestsCache = pullRequestCache;
|
|
this.cache = pullRequestCache;
|
|
this.updateItems();
|
|
}
|
|
|
|
private static async init(
|
|
http: GitlabHttp,
|
|
repo: string,
|
|
author: string | null,
|
|
ignorePrAuthor: boolean,
|
|
): Promise<GitlabPrCache> {
|
|
const res = new GitlabPrCache(repo, author, ignorePrAuthor);
|
|
const isSynced = memCache.get<true | undefined>('gitlab-pr-cache-synced');
|
|
|
|
if (!isSynced) {
|
|
await res.sync(http);
|
|
memCache.set('gitlab-pr-cache-synced', true);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
private getPrs(): GitlabPr[] {
|
|
return this.items;
|
|
}
|
|
|
|
static async getPrs(
|
|
http: GitlabHttp,
|
|
repo: string,
|
|
author: string | null,
|
|
ignorePrAuthor: boolean,
|
|
): Promise<GitlabPr[]> {
|
|
const prCache = await GitlabPrCache.init(
|
|
http,
|
|
repo,
|
|
author,
|
|
ignorePrAuthor,
|
|
);
|
|
return prCache.getPrs();
|
|
}
|
|
|
|
private setPr(pr: GitlabPr): void {
|
|
logger.debug(`Adding PR #${pr.number} to the PR cache`);
|
|
this.cache.items[pr.number] = pr;
|
|
this.updateItems();
|
|
}
|
|
|
|
static async setPr(
|
|
http: GitlabHttp,
|
|
repo: string,
|
|
author: string | null,
|
|
item: GitlabPr,
|
|
ignorePrAuthor: boolean,
|
|
): Promise<void> {
|
|
const prCache = await GitlabPrCache.init(
|
|
http,
|
|
repo,
|
|
author,
|
|
ignorePrAuthor,
|
|
);
|
|
prCache.setPr(item);
|
|
}
|
|
|
|
private async sync(http: GitlabHttp): Promise<GitlabPrCache> {
|
|
logger.debug('Syncing PR list');
|
|
|
|
const searchParams: Record<string, string> = {
|
|
per_page: '100',
|
|
order_by: 'updated_at',
|
|
sort: 'desc',
|
|
};
|
|
|
|
const opts: GitlabHttpOptions = { paginate: true };
|
|
|
|
const updated_after = this.cache.updated_at;
|
|
if (updated_after) {
|
|
opts.cacheProvider = repoCacheProvider;
|
|
searchParams.updated_after = updated_after;
|
|
}
|
|
|
|
if (!this.ignorePrAuthor) {
|
|
searchParams.scope = 'created_by_me';
|
|
}
|
|
|
|
const query: string | null = getQueryString(searchParams);
|
|
const { body: items } = await http.getJson(
|
|
`/projects/${this.repo}/merge_requests?${query}`,
|
|
opts,
|
|
GitLabMergeRequestsSchema,
|
|
);
|
|
|
|
if (items.length) {
|
|
for (const item of items) {
|
|
const id = item.iid;
|
|
this.cache.items[id] = prInfo(item);
|
|
}
|
|
|
|
const [{ updated_at }] = items;
|
|
this.cache.updated_at = updated_at.replace(regEx(/\.\d\d\dZ$/), 'Z');
|
|
}
|
|
|
|
this.updateItems();
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Ensure the pr cache starts with the most recent PRs.
|
|
*/
|
|
private updateItems(): void {
|
|
this.items = Object.values(this.cache.items).sort(
|
|
(a, b) => b.number - a.number,
|
|
);
|
|
}
|
|
}
|