Skip to content
This repository has been archived by the owner on May 29, 2023. It is now read-only.

Commit

Permalink
feat: add ability to filter by type (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinBeckwith committed Nov 9, 2018
1 parent 94a9562 commit 6dddaf7
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 59 deletions.
11 changes: 8 additions & 3 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {reconcileLabels} from './label';
import {reconcileUsers, reconcileTeams, reconcileRepos} from './users';
import {syncRepoSettings} from './repos';
import * as updateNotifier from 'update-notifier';
import {Flags} from './types';

const pkg = require('../../package.json');

Expand All @@ -39,10 +40,12 @@ const cli = meow(
--language Filter by a given language
--repo Filter by a given repository
--pr Filter to show only PRs
--type Filter to show only issues of a given type
--pri Filter to show only issues with a given priorty
Examples
$ sloth [--csv][--api]
$ sloth issues [--csv][--untriaged][--outOfSLO][--language][--repo][--api][--pr]
$ sloth issues [--csv][--untriaged][--outOfSLO][--language][--repo][--api][--pr][--type]
$ sloth apis
$ sloth tag-issues
$ sloth users
Expand All @@ -59,7 +62,9 @@ const cli = meow(
outOfSLO: {type: 'boolean'},
csv: {type: 'boolean'},
api: {type: 'string'},
pr: {type: 'boolean'}
pr: {type: 'boolean'},
type: {type: 'string'},
pri: {type: 'string'}
}
});

Expand All @@ -80,7 +85,7 @@ switch (cmd) {
p = reconcileUsers();
break;
case 'issues':
p = showIssues(cli.flags);
p = showIssues(cli.flags as Flags);
break;
case 'repos':
p = reconcileRepos();
Expand Down
102 changes: 50 additions & 52 deletions src/issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import * as Octokit from '@octokit/rest';

import {getPri} from './slo';
import {getPri, getType} from './slo';
import {Flags, Issue, IssueResult, Repo} from './types';
import {octo, repos} from './util';

Expand All @@ -23,15 +23,19 @@ import {isTriaged, isOutOfSLO, hasLabel, isApi, isPullRequest, hoursOld, getApi}
const truncate = require('truncate');
const CSV = require('csv-string');

export async function getIssues(): Promise<IssueResult[]> {
export async function getIssues(flags?: Flags): Promise<IssueResult[]> {
const promises = new Array<Promise<IssueResult>>();
repos.forEach(repo => {
promises.push(getRepoIssues(repo));
// if we're filtering by --language, don't even snag the issues
if (flags && flags.language && repo.language !== flags.language) {
return;
}
promises.push(getRepoIssues(repo, flags));
});
return Promise.all(promises);
}

async function getRepoIssues(repo: Repo): Promise<IssueResult> {
async function getRepoIssues(repo: Repo, flags?: Flags): Promise<IssueResult> {
const [owner, name] = repo.repo.split('/');
const result = {issues: new Array<Issue>(), repo};
let res: Octokit.AnyResponse;
Expand All @@ -45,10 +49,46 @@ async function getRepoIssues(repo: Repo): Promise<IssueResult> {
console.error(e);
throw e;
}
for (const r of res.data) {
for (const r of res.data as Issue[]) {
r.language = repo.language;
r.repo = repo.repo;
result.issues.push(r);
r.type = getType(r);
r.api = getApi(r);
r.isOutOfSLO = isOutOfSLO(r);
r.isTriaged = isTriaged(r);
r.pri = getPri(r);
r.isPR = isPullRequest(r);

let use = true;
if (flags) {
if (flags.api && r.api !== flags.api) {
use = false;
}
if (flags.repo && r.repo !== flags.repo) {
use = false;
}
if (flags.api && r.api !== flags.api) {
use = false;
}
if (flags.outOfSlo && !r.isOutOfSLO) {
use = false;
}
if (flags.untriaged && r.isTriaged) {
use = false;
}
if (flags.pri && r.pri !== flags.pri) {
use = false;
}
if (flags.pr && !r.isPR) {
use = false;
}
if (flags.type && r.type !== flags.type) {
use = false;
}
}
if (use) {
result.issues.push(r);
}
}
i++;
} while (res.headers && res.headers.link &&
Expand All @@ -72,8 +112,6 @@ export async function tagIssues() {
repos.forEach(r => {
r.issues.forEach(i => {
const [owner, name] = r.repo.repo.split('/');
i.isTriaged = isTriaged(i);
i.isOutOfSLO = isOutOfSLO(i);
i.repo = name;
i.owner = owner;
if (!i.isTriaged && !hasLabel(i, 'triage me') &&
Expand Down Expand Up @@ -122,52 +160,12 @@ function untagIssue(
});
}

export async function showIssues(flags: Flags) {
const options = {
csv: flags.csv,
language: flags.language,
outOfSLO: flags.outOfSlo,
untriaged: flags.untriaged,
repo: flags.repo,
api: flags.api,
pr: flags.pr
};
const repos = await getIssues();
// tslint:disable-next-line no-any
export async function showIssues(options: Flags) {
const repos = await getIssues(options);
const issues = new Array<Issue>();
repos.forEach(r => {
if (options.language &&
options.language.toLowerCase() !== r.repo.language.toLowerCase()) {
return;
}
if (options.repo &&
options.repo.toLowerCase() !== r.repo.repo.toLowerCase()) {
return;
}
r.issues.forEach(i => {
if (options.pr) {
if (!isPullRequest(i)) {
return;
}
} else {
if (isPullRequest(i)) {
return;
}
}
i.api = getApi(i);
if (options.api && !isApi(i, options.api)) {
return;
}
i.isTriaged = isTriaged(i);
if (options.untriaged && i.isTriaged) {
return;
}
i.isOutOfSLO = isOutOfSLO(i);
if (options.outOfSLO && !i.isOutOfSLO) {
return;
}
i.pri = getPri(i);
issues.push(i);
});
r.issues.forEach(i => issues.push(i));
});
let table: Table;
const output = new Array<string>();
Expand Down
14 changes: 12 additions & 2 deletions src/slo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

import {getIssues} from './issue';
import {ApiResult, Issue, IssueResult, LanguageResult, RepoResult} from './types';
import {ApiResult, Flags, Issue, IssueResult, LanguageResult, RepoResult} from './types';
import {languages} from './util';

import Table = require('cli-table');
Expand Down Expand Up @@ -235,6 +235,16 @@ export function getApi(i: Issue) {
return undefined;
}

export function getType(i: Issue) {
for (const label of i.labels) {
const name = label.name.toLowerCase();
if (name.startsWith('type: ')) {
return name.slice(6);
}
}
return undefined;
}

/**
* Determine if an issue has been triaged. An issue is triaged if:
* - It has a `priority` label OR
Expand Down Expand Up @@ -418,7 +428,7 @@ export async function showApiSLOs(cli: meow.Result) {

export async function showLanguageSLOs(cli: meow.Result) {
const output = new Array<string>();
const issues = await getIssues();
const issues = await getIssues(cli.flags as Flags);
const res = getLanguageResults(issues, cli.flags.api);
const languageHeader =
['Language', 'Total', 'P0', 'P1', 'P2', 'Untriaged', 'Out of SLO'];
Expand Down
13 changes: 11 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ export interface Member {
}

export interface Issue {
isPR?: boolean;
api?: string;
type?: string;
pri?: string;
language: string;
repo: string;
Expand Down Expand Up @@ -154,8 +156,15 @@ export interface Organization {
}

export interface Flags {
// tslint:disable-next-line no-any
[index: string]: any;
csv: boolean;
language: string;
outOfSlo: boolean;
untriaged: boolean;
repo: string;
api: string;
pr: boolean;
type: string;
pri: string;
}

export interface GetBranchProtectionResult {
Expand Down

0 comments on commit 6dddaf7

Please sign in to comment.