Skip to content
This repository was archived by the owner on Jul 1, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/compute-pr-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as Comments from "./comments";
import { PrInfo, BotError, BotEnsureRemovedFromProject, BotNoPackages, FileInfo } from "./pr-info";
import { CIResult } from "./util/CIResult";
import { ReviewInfo } from "./pr-info";
import { noNulls, flatten, unique, sameUser, daysSince, sha256 } from "./util/util";
import { noNullish, flatten, unique, sameUser, daysSince, sha256 } from "./util/util";

type ColumnName =
| "Needs Maintainer Action"
Expand Down Expand Up @@ -150,10 +150,10 @@ function extendPrInfo(info: PrInfo): ExtendedPrInfo {
const noOtherOwners = allOwners.every(isAuthor);
const tooManyOwners = allOwners.length > 50;
const editsOwners = info.pkgInfo.some(p => p.kind === "edit" && p.addedOwners.length + p.deletedOwners.length > 0);
const packages = noNulls(info.pkgInfo.map(p => p.name));
const packages = noNullish(info.pkgInfo.map(p => p.name));
const hasMultiplePackages = packages.length > 1;
const hasTests = info.pkgInfo.some(p => p.files.some(f => f.kind === "test"));
const newPackages = noNulls(info.pkgInfo.map(p => p.kind === "add" ? p.name : null));
const newPackages = noNullish(info.pkgInfo.map(p => p.kind === "add" ? p.name : null));
const hasNewPackages = newPackages.length > 0;
const requireMaintainer = editsInfra || editsConfig || hasMultiplePackages || !hasTests || hasNewPackages || tooManyOwners;
const blessable = !(hasNewPackages || editsInfra || noOtherOwners);
Expand Down Expand Up @@ -202,7 +202,7 @@ function extendPrInfo(info: PrInfo): ExtendedPrInfo {
}

function getPendingCriticalPackages() {
return noNulls(info.pkgInfo.map(p =>
return noNullish(info.pkgInfo.map(p =>
p.popularityLevel === "Critical" && !p.owners.some(o => approvedReviews.some(r => sameUser(o, r.reviewer)))
? p.name : null));
}
Expand Down
8 changes: 4 additions & 4 deletions src/execute-pr-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { PR as PRQueryResult, PR_repository_pullRequest } from "./queries/schema
import { Actions, LabelNames, LabelName } from "./compute-pr-actions";
import { createMutation, mutate } from "./graphql-client";
import { getProjectBoardColumns, getLabels } from "./util/cachedQueries";
import { noNulls, flatten } from "./util/util";
import { noNullish, flatten } from "./util/util";
import * as comment from "./util/comment";

// https://github.com/DefinitelyTyped/DefinitelyTyped/projects/5
Expand All @@ -22,7 +22,7 @@ export const deleteProjectCard = `mutation($input: DeleteProjectCardInput!) { de
export async function executePrActions(actions: Actions, info: PRQueryResult, dry?: boolean) {
const pr = info.repository?.pullRequest!;
const botComments: ParsedComment[] = getBotComments(pr);
const mutations = noNulls([
const mutations = noNullish([
...await getMutationsForLabels(actions, pr),
...await getMutationsForProjectChanges(actions, pr),
...getMutationsForComments(actions, pr.id, botComments),
Expand All @@ -38,7 +38,7 @@ export async function executePrActions(actions: Actions, info: PRQueryResult, dr

async function getMutationsForLabels(actions: Actions, pr: PR_repository_pullRequest) {
if (!actions.shouldUpdateLabels) return []
const labels = noNulls(pr.labels?.nodes!).map(l => l.name);
const labels = noNullish(pr.labels?.nodes).map(l => l.name);
const makeMutations = async (pred: (l: LabelName) => boolean, query: string) => {
const labels = LabelNames.filter(pred);
return labels.length === 0 ? null
Expand Down Expand Up @@ -72,7 +72,7 @@ async function getMutationsForProjectChanges(actions: Actions, pr: PR_repository
type ParsedComment = { id: string, body: string, tag: string, status: string };

function getBotComments(pr: PR_repository_pullRequest): ParsedComment[] {
return noNulls((pr.comments.nodes ?? [])
return noNullish((pr.comments.nodes ?? [])
.filter(comment => comment?.author?.login === "typescript-bot")
.map(c => {
const { id, body } = c!, parsed = comment.parse(body);
Expand Down
10 changes: 5 additions & 5 deletions src/pr-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { getMonthlyDownloadCount } from "./util/npm";
import { client } from "./graphql-client";
import { ApolloQueryResult } from "apollo-boost";
import { fetchFile as defaultFetchFile } from "./util/fetchFile";
import { noNulls, notUndefined, findLast, forEachReverse, sameUser, authorNotBot, latestDate } from "./util/util";
import { noNullish, findLast, forEachReverse, sameUser, authorNotBot, latestDate } from "./util/util";
import * as comment from "./util/comment";
import * as HeaderParser from "definitelytyped-header-parser";
import * as jsonDiff from "fast-json-patch";
Expand Down Expand Up @@ -219,15 +219,15 @@ export async function deriveStateForPR(
const reopenedDate = getReopenedDate(prInfo.timelineItems);

const pkgInfoEtc = await getPackageInfosEtc(
noNulls(prInfo.files?.nodes).map(f => f.path).sort(),
noNullish(prInfo.files?.nodes).map(f => f.path).sort(),
headCommit.oid, fetchFile, async name => await getDownloads(name, lastPushDate));
if (pkgInfoEtc instanceof Error) return botError(prInfo.number, pkgInfoEtc.message);
const { pkgInfo, popularityLevel } = pkgInfoEtc;
if (!pkgInfo.some(p => p.name)) return botNoPackages(prInfo.number);

const reviews = getReviews(prInfo);
const latestReview = latestDate(...reviews.map(r => r.date));
const comments = noNulls(prInfo.comments.nodes || []);
const comments = noNullish(prInfo.comments.nodes);
const mergeOfferDate = getMergeOfferDate(comments, headCommit.abbreviatedOid);
const mergeRequest = getMergeRequest(comments,
pkgInfo.length === 1 ? [author, ...pkgInfo[0].owners] : [author],
Expand Down Expand Up @@ -465,7 +465,7 @@ function getReviews(prInfo: PR_repository_pullRequest) {
const headCommitOid: string = prInfo.headRefOid;
const reviews: ReviewInfo[] = [];
// Do this in reverse order so we can detect up-to-date-reviews correctly
for (const r of noNulls(prInfo.reviews.nodes).reverse()) {
for (const r of noNullish(prInfo.reviews.nodes).reverse()) {
const [reviewer, date] = [r?.author?.login, new Date(r.submittedAt)];
// Skip nulls
if (!(r?.commit && reviewer)) continue;
Expand Down Expand Up @@ -522,5 +522,5 @@ async function getOwnersOfPackage(packageName: string, version: string, fetchFil
} catch (e) {
if (e instanceof Error) return new Error(`error parsing owners: ${e.message}`);
}
return parsed!.contributors.map(c => c.githubUsername).filter(notUndefined);
return noNullish(parsed!.contributors.map(c => c.githubUsername));
}
15 changes: 5 additions & 10 deletions src/util/cachedQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,26 @@ import { GetProjectColumns as GetProjectColumnsResult } from "../queries/schema/
import { GetLabels as GetLabelsResult } from "../queries/schema/GetLabels";
import { createCache } from "../ttl-cache";
import { client } from "../graphql-client";
import { noNullish } from "./util";

const cache = createCache();

export async function getProjectBoardColumns() {
return cache.getAsync("project board colum names", Infinity, async () => {
const res = (await query<GetProjectColumnsResult>(GetProjectColumns))
.repository?.project?.columns.nodes?.filter(defined)
?? [];
const res = noNullish((await query<GetProjectColumnsResult>(GetProjectColumns))
.repository?.project?.columns.nodes);
return res.sort((a,b) => a.name.localeCompare(b.name));
});
}

export async function getLabels() {
return await cache.getAsync("label ids", Infinity, async () => {
const res = (await query<GetLabelsResult>(GetLabels))
.repository?.labels?.nodes?.filter(defined)
?? [];
const res = noNullish((await query<GetLabelsResult>(GetLabels))
.repository?.labels?.nodes);
return res.sort((a,b) => a.name.localeCompare(b.name));
});
}

function defined<T>(arg: T | null | undefined): arg is T {
return arg != null;
}

async function query<T>(gql: any): Promise<T> {
const res = await client.query<T>({
query: gql,
Expand Down
4 changes: 1 addition & 3 deletions src/util/util.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import * as crypto from "crypto";
import * as moment from "moment";

export function noNulls<T>(arr: ReadonlyArray<T | null | undefined> | null | undefined): T[] {
export function noNullish<T>(arr: ReadonlyArray<T | null | undefined> | null | undefined): T[] {
if (arr == null) return [];
return arr.filter(arr => arr != null) as T[];
}

export function notUndefined<T>(arg: T | undefined): arg is T { return arg !== undefined; }

export function flatten<T>(xs: T[][]) {
return ([] as T[]).concat(...xs);
}
Expand Down