Merge pull request #1639 from github/shati-patel/repo-count
Implement query history label for variant analysis items
This commit is contained in:
@@ -584,11 +584,3 @@ export async function* walkDirectory(dir: string): AsyncIterableIterator<string>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluralizes a word.
|
||||
* Example: Returns "N repository" if N is one, "N repositories" otherwise.
|
||||
*/
|
||||
export function pluralize(numItems: number | undefined, singular: string, plural: string): string {
|
||||
return numItems ? `${numItems} ${numItems === 1 ? singular : plural}` : '';
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@ import { env } from 'vscode';
|
||||
import * as path from 'path';
|
||||
import { QueryHistoryConfig } from './config';
|
||||
import { LocalQueryInfo } from './query-results';
|
||||
import { getRawQueryName, QueryHistoryInfo } from './query-history-info';
|
||||
import { buildRepoLabel, getRawQueryName, QueryHistoryInfo } from './query-history-info';
|
||||
import { RemoteQueryHistoryItem } from './remote-queries/remote-query-history-item';
|
||||
import { pluralize } from './helpers';
|
||||
import { VariantAnalysisHistoryItem } from './remote-queries/variant-analysis-history-item';
|
||||
import { assertNever } from './pure/helpers-pure';
|
||||
import { pluralize } from './pure/word';
|
||||
|
||||
interface InterpolateReplacements {
|
||||
t: string; // Start time
|
||||
@@ -79,23 +79,12 @@ export class HistoryItemLabelProvider {
|
||||
};
|
||||
}
|
||||
|
||||
// Return the number of repositories queried if available. Otherwise, use the controller repository name.
|
||||
private buildRepoLabel(item: RemoteQueryHistoryItem): string {
|
||||
const repositoryCount = item.remoteQuery.repositoryCount;
|
||||
|
||||
if (repositoryCount) {
|
||||
return pluralize(repositoryCount, 'repository', 'repositories');
|
||||
}
|
||||
|
||||
return `${item.remoteQuery.controllerRepository.owner}/${item.remoteQuery.controllerRepository.name}`;
|
||||
}
|
||||
|
||||
private getRemoteInterpolateReplacements(item: RemoteQueryHistoryItem): InterpolateReplacements {
|
||||
const resultCount = item.resultCount ? `(${pluralize(item.resultCount, 'result', 'results')})` : '';
|
||||
return {
|
||||
t: new Date(item.remoteQuery.executionStartTime).toLocaleString(env.language),
|
||||
q: `${item.remoteQuery.queryName} (${item.remoteQuery.language})`,
|
||||
d: this.buildRepoLabel(item),
|
||||
d: buildRepoLabel(item),
|
||||
r: resultCount,
|
||||
s: item.status,
|
||||
f: path.basename(item.remoteQuery.queryFilePath),
|
||||
@@ -108,7 +97,7 @@ export class HistoryItemLabelProvider {
|
||||
return {
|
||||
t: new Date(item.variantAnalysis.executionStartTime).toLocaleString(env.language),
|
||||
q: `${item.variantAnalysis.query.name} (${item.variantAnalysis.query.language})`,
|
||||
d: 'TODO',
|
||||
d: buildRepoLabel(item),
|
||||
r: resultCount,
|
||||
s: item.status,
|
||||
f: path.basename(item.variantAnalysis.query.filePath),
|
||||
|
||||
8
extensions/ql-vscode/src/pure/word.ts
Normal file
8
extensions/ql-vscode/src/pure/word.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Pluralizes a word.
|
||||
* Example: Returns "N repository" if N is one, "N repositories" otherwise.
|
||||
*/
|
||||
|
||||
export function pluralize(numItems: number | undefined, singular: string, plural: string): string {
|
||||
return numItems !== undefined ? `${numItems} ${numItems === 1 ? singular : plural}` : '';
|
||||
}
|
||||
@@ -2,6 +2,8 @@ import { RemoteQueryHistoryItem } from './remote-queries/remote-query-history-it
|
||||
import { VariantAnalysisHistoryItem } from './remote-queries/variant-analysis-history-item';
|
||||
import { LocalQueryInfo } from './query-results';
|
||||
import { assertNever } from './pure/helpers-pure';
|
||||
import { pluralize } from './pure/word';
|
||||
import { hasRepoScanCompleted } from './remote-queries/shared/variant-analysis';
|
||||
|
||||
export type QueryHistoryInfo = LocalQueryInfo | RemoteQueryHistoryItem | VariantAnalysisHistoryItem;
|
||||
|
||||
@@ -43,3 +45,22 @@ export function getQueryText(item: QueryHistoryInfo): string {
|
||||
assertNever(item);
|
||||
}
|
||||
}
|
||||
|
||||
export function buildRepoLabel(item: RemoteQueryHistoryItem | VariantAnalysisHistoryItem): string {
|
||||
if (item.t === 'remote') {
|
||||
// Return the number of repositories queried if available. Otherwise, use the controller repository name.
|
||||
const repositoryCount = item.remoteQuery.repositoryCount;
|
||||
|
||||
if (repositoryCount) {
|
||||
return pluralize(repositoryCount, 'repository', 'repositories');
|
||||
}
|
||||
return `${item.remoteQuery.controllerRepository.owner}/${item.remoteQuery.controllerRepository.name}`;
|
||||
} else if (item.t === 'variant-analysis') {
|
||||
const totalScannedRepositoryCount = item.variantAnalysis.scannedRepos?.length ?? 0;
|
||||
const completedRepositoryCount = item.variantAnalysis.scannedRepos?.filter(repo => hasRepoScanCompleted(repo)).length ?? 0;
|
||||
|
||||
return `${completedRepositoryCount}/${pluralize(totalScannedRepositoryCount, 'repository', 'repositories')}`; // e.g. "2/3 repositories"
|
||||
} else {
|
||||
assertNever(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,7 @@ import * as fs from 'fs-extra';
|
||||
import { window, commands, Uri, ExtensionContext, QuickPickItem, workspace, ViewColumn } from 'vscode';
|
||||
import { Credentials } from '../authentication';
|
||||
import { UserCancellationException } from '../commandRunner';
|
||||
import {
|
||||
showInformationMessageWithAction,
|
||||
pluralize
|
||||
} from '../helpers';
|
||||
import { showInformationMessageWithAction } from '../helpers';
|
||||
import { logger } from '../logging';
|
||||
import { QueryHistoryManager } from '../query-history';
|
||||
import { createGist } from './gh-api/gh-actions-api-client';
|
||||
@@ -16,6 +13,7 @@ import { generateMarkdown } from './remote-queries-markdown-generation';
|
||||
import { RemoteQuery } from './remote-query';
|
||||
import { AnalysisResults, sumAnalysesResults } from './shared/analysis-result';
|
||||
import { RemoteQueryHistoryItem } from './remote-query-history-item';
|
||||
import { pluralize } from '../pure/word';
|
||||
|
||||
/**
|
||||
* Exports the results of the given or currently-selected remote query.
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
showAndLogErrorMessage,
|
||||
showAndLogInformationMessage,
|
||||
tryGetQueryMetadata,
|
||||
pluralize,
|
||||
tmpDir,
|
||||
} from '../helpers';
|
||||
import { Credentials } from '../authentication';
|
||||
@@ -24,6 +23,7 @@ import { RemoteQuery } from './remote-query';
|
||||
import { RemoteQuerySubmissionResult } from './remote-query-submission-result';
|
||||
import { QueryMetadata } from '../pure/interface-types';
|
||||
import { getErrorMessage, REPO_REGEX } from '../pure/helpers-pure';
|
||||
import { pluralize } from '../pure/word';
|
||||
import * as ghApiClient from './gh-api/gh-api-client';
|
||||
import { getRepositorySelection, isValidSelection, RepositorySelection } from './repository-selection';
|
||||
import { parseVariantAnalysisQueryLanguage, VariantAnalysisSubmission } from './shared/variant-analysis';
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { expect } from 'chai';
|
||||
|
||||
import { QueryStatus } from '../../src/query-status';
|
||||
import { getQueryHistoryItemId, getQueryText, getRawQueryName } from '../../src/query-history-info';
|
||||
import { buildRepoLabel, getQueryHistoryItemId, getQueryText, getRawQueryName } from '../../src/query-history-info';
|
||||
import { VariantAnalysisHistoryItem } from '../../src/remote-queries/variant-analysis-history-item';
|
||||
import { createMockVariantAnalysis } from '../../src/vscode-tests/factories/remote-queries/shared/variant-analysis';
|
||||
import { createMockScannedRepos } from '../../src/vscode-tests/factories/remote-queries/shared/scanned-repositories';
|
||||
import { createMockLocalQueryInfo } from '../../src/vscode-tests/factories/local-queries/local-query-history-item';
|
||||
import { createMockRemoteQueryHistoryItem } from '../../src/vscode-tests/factories/remote-queries/remote-query-history-item';
|
||||
import { VariantAnalysisRepoStatus, VariantAnalysisStatus } from '../../src/remote-queries/shared/variant-analysis';
|
||||
|
||||
describe('Query history info', () => {
|
||||
|
||||
@@ -18,7 +20,15 @@ describe('Query history info', () => {
|
||||
status: QueryStatus.InProgress,
|
||||
completed: false,
|
||||
historyItemId: 'abc123',
|
||||
variantAnalysis: createMockVariantAnalysis()
|
||||
variantAnalysis: createMockVariantAnalysis(
|
||||
VariantAnalysisStatus.InProgress,
|
||||
createMockScannedRepos([
|
||||
VariantAnalysisRepoStatus.Succeeded,
|
||||
VariantAnalysisRepoStatus.Pending,
|
||||
VariantAnalysisRepoStatus.InProgress,
|
||||
VariantAnalysisRepoStatus.Canceled,
|
||||
])
|
||||
),
|
||||
};
|
||||
|
||||
describe('getRawQueryName', () => {
|
||||
@@ -80,4 +90,61 @@ describe('Query history info', () => {
|
||||
expect(queryText).to.equal(variantAnalysisHistoryItem.variantAnalysis.query.text);
|
||||
});
|
||||
});
|
||||
|
||||
describe('buildRepoLabel', () => {
|
||||
describe('repo label for remote query history items', () => {
|
||||
it('should return controller repo when `repositoryCount` is 0', () => {
|
||||
const repoLabel = buildRepoLabel(remoteQueryHistoryItem);
|
||||
const expectedRepoLabel = `${remoteQueryHistoryItem.remoteQuery.controllerRepository.owner}/${remoteQueryHistoryItem.remoteQuery.controllerRepository.name}`;
|
||||
|
||||
expect(repoLabel).to.equal(expectedRepoLabel);
|
||||
});
|
||||
it('should return number of repositories when `repositoryCount` is non-zero', () => {
|
||||
const remoteQueryHistoryItem2 = createMockRemoteQueryHistoryItem({repositoryCount: 3});
|
||||
const repoLabel2 = buildRepoLabel(remoteQueryHistoryItem2);
|
||||
const expectedRepoLabel2 = '3 repositories';
|
||||
|
||||
expect(repoLabel2).to.equal(expectedRepoLabel2);
|
||||
});
|
||||
});
|
||||
describe('repo label for variant analysis history items', () => {
|
||||
it('should return label when `totalScannedRepositoryCount` is 0', () => {
|
||||
const variantAnalysisHistoryItem0: VariantAnalysisHistoryItem = {
|
||||
t: 'variant-analysis',
|
||||
status: QueryStatus.InProgress,
|
||||
completed: false,
|
||||
historyItemId: 'abc123',
|
||||
variantAnalysis: createMockVariantAnalysis(
|
||||
VariantAnalysisStatus.InProgress,
|
||||
createMockScannedRepos([])
|
||||
),
|
||||
};
|
||||
const repoLabel0 = buildRepoLabel(variantAnalysisHistoryItem0);
|
||||
|
||||
expect(repoLabel0).to.equal('0/0 repositories');
|
||||
});
|
||||
it('should return label when `totalScannedRepositoryCount` is 1', () => {
|
||||
const variantAnalysisHistoryItem1: VariantAnalysisHistoryItem = {
|
||||
t: 'variant-analysis',
|
||||
status: QueryStatus.InProgress,
|
||||
completed: false,
|
||||
historyItemId: 'abc123',
|
||||
variantAnalysis: createMockVariantAnalysis(
|
||||
VariantAnalysisStatus.InProgress,
|
||||
createMockScannedRepos([
|
||||
VariantAnalysisRepoStatus.Pending,
|
||||
])
|
||||
),
|
||||
};
|
||||
|
||||
const repoLabel1 = buildRepoLabel(variantAnalysisHistoryItem1);
|
||||
expect(repoLabel1).to.equal('0/1 repository');
|
||||
});
|
||||
it('should return label when `totalScannedRepositoryCount` is greater than 1', () => {
|
||||
const repoLabel = buildRepoLabel(variantAnalysisHistoryItem);
|
||||
|
||||
expect(repoLabel).to.equal('2/4 repositories');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
20
extensions/ql-vscode/test/pure-tests/word.test.ts
Normal file
20
extensions/ql-vscode/test/pure-tests/word.test.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { expect } from 'chai';
|
||||
|
||||
import { pluralize } from '../../src/pure/word';
|
||||
|
||||
describe('word helpers', () => {
|
||||
describe('pluralize', () => {
|
||||
it('should return the plural form if the number is 0', () => {
|
||||
expect(pluralize(0, 'thing', 'things')).to.eq('0 things');
|
||||
});
|
||||
it('should return the singular form if the number is 1', () => {
|
||||
expect(pluralize(1, 'thing', 'things')).to.eq('1 thing');
|
||||
});
|
||||
it('should return the plural form if the number is greater than 1', () => {
|
||||
expect(pluralize(7, 'thing', 'things')).to.eq('7 things');
|
||||
});
|
||||
it('should return the empty string if the number is undefined', () => {
|
||||
expect(pluralize(undefined, 'thing', 'things')).to.eq('');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user