renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
134 lines • 5.33 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ForgejoPrCache = void 0;
const tslib_1 = require("tslib");
const dequal_1 = require("dequal");
const luxon_1 = require("luxon");
const error_messages_1 = require("../../../constants/error-messages");
const logger_1 = require("../../../logger");
const memCache = tslib_1.__importStar(require("../../../util/cache/memory"));
const repository_1 = require("../../../util/cache/repository");
const url_1 = require("../../../util/url");
const utils_1 = require("./utils");
class ForgejoPrCache {
repo;
ignorePrAuthor;
author;
cache;
items = [];
constructor(repo, ignorePrAuthor, author) {
this.repo = repo;
this.ignorePrAuthor = ignorePrAuthor;
this.author = author;
const repoCache = (0, repository_1.getCache)();
repoCache.platform ??= {};
repoCache.platform.forgejo ??= {};
let pullRequestCache = repoCache.platform.forgejo.pullRequestsCache;
if (!pullRequestCache || pullRequestCache.author !== author) {
pullRequestCache = {
items: {},
updated_at: null,
author,
};
}
repoCache.platform.forgejo.pullRequestsCache = pullRequestCache;
this.cache = pullRequestCache;
this.updateItems();
}
static forceSync() {
memCache.set('forgejo-pr-cache-synced', false);
}
static async init(http, repo, ignorePrAuthor, author) {
const res = new ForgejoPrCache(repo, ignorePrAuthor, author);
const isSynced = memCache.get('forgejo-pr-cache-synced');
if (!isSynced) {
await res.sync(http);
memCache.set('forgejo-pr-cache-synced', true);
}
return res;
}
getPrs() {
return this.items;
}
static async getPrs(http, repo, ignorePrAuthor, author) {
const prCache = await ForgejoPrCache.init(http, repo, ignorePrAuthor, author);
return prCache.getPrs();
}
setPr(item) {
this.cache.items[item.number] = item;
this.updateItems();
}
static async setPr(http, repo, ignorePrAuthor, author, item) {
const prCache = await ForgejoPrCache.init(http, repo, ignorePrAuthor, author);
prCache.setPr(item);
}
reconcile(rawItems) {
const { items } = this.cache;
let { updated_at } = this.cache;
const cacheTime = updated_at ? luxon_1.DateTime.fromISO(updated_at) : null;
let needNextPage = true;
for (const rawItem of rawItems) {
if (!rawItem) {
logger_1.logger.warn('Forgejo PR is empty, throwing temporary error');
// Forgejo API sometimes returns empty PRs, so we throw a temporary error
// https://github.com/go-forgejo/forgejo/blob/fcd096231ac2deaefbca10a7db1b9b01f1da93d7/services/convert/pull.go#L34-L52
throw new Error(error_messages_1.TEMPORARY_ERROR);
}
const id = rawItem.number;
const newItem = (0, utils_1.toRenovatePR)(rawItem, this.author);
if (!newItem) {
continue;
}
const oldItem = items[id];
if ((0, dequal_1.dequal)(oldItem, newItem)) {
needNextPage = false;
continue;
}
items[id] = newItem;
const itemTime = luxon_1.DateTime.fromISO(rawItem.updated_at);
if (!cacheTime || itemTime > cacheTime) {
updated_at = rawItem.updated_at;
}
}
this.cache.updated_at = updated_at;
return needNextPage;
}
async sync(http) {
let query = (0, url_1.getQueryString)({
state: 'all',
sort: 'recentupdate',
// Fetch 100 PRs on the first run to ensure we have the most recent PRs.
// Forgejo will cap appropriate (50 by default, see `MAX_RESPONSE_ITEMS`).
// https://docs.forgejo.com/administration/config-cheat-sheet#api-api
// https://forgejo.org/docs/latest/admin/config-cheat-sheet/#api-api
limit: this.items.length ? 20 : 100,
// Supported since Forgejo v10.0.0.
// Will be ignored by older instances.
...(this.ignorePrAuthor ? {} : { poster: this.author }),
});
while (query) {
// TODO: use zod, typescript can't infer the type of the response #22198
const res = await http.getJsonUnchecked(`${utils_1.API_PATH}/repos/${this.repo}/pulls?${query}`, {
memCache: false,
paginate: false,
});
const needNextPage = this.reconcile(res.body);
if (!needNextPage) {
break;
}
const uri = (0, url_1.parseUrl)((0, url_1.parseLinkHeader)(res.headers.link)?.next?.url);
query = uri ? uri.search : null;
}
this.updateItems();
return this;
}
/**
* Ensure the pr cache starts with the most recent PRs.
* JavaScript ensures that the cache is sorted by PR number.
*/
updateItems() {
this.items = Object.values(this.cache.items).reverse();
}
}
exports.ForgejoPrCache = ForgejoPrCache;
//# sourceMappingURL=pr-cache.js.map