Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
23 changes: 15 additions & 8 deletions extensions/ql-vscode/src/remote-queries/run-remote-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ async function findPackRoot(queryFile: string): Promise<string> {
while (!(await fs.pathExists(path.join(dir, 'qlpack.yml')))) {
dir = path.dirname(dir);
if (isFileSystemRoot(dir)) {
// there is no qlpack.yml in this direcory or any parent directory.
// there is no qlpack.yml in this directory or any parent directory.
// just use the query file's directory as the pack root.
return path.dirname(queryFile);
}
Expand Down Expand Up @@ -349,36 +349,43 @@ async function runRemoteQueriesApiRequest(
const eol = os.EOL;
const eol2 = os.EOL + os.EOL;

/**
* Returns "N repository" if N is one, "N repositories" otherwise.
*/
function pluralizeRepositories(numRepositories: number) {
return `${numRepositories} ${numRepositories === 1 ? 'repository' : 'repositories'}`;
}

// exported for testing only
export function parseResponse(owner: string, repo: string, response: QueriesResponse) {
const repositoriesQueried = response.repositories_queried;
const numRepositoriesQueried = repositoriesQueried.length;

const popupMessage = `Successfully scheduled runs on ${numRepositoriesQueried} repositories. [Click here to see the progress](https://github.com/${owner}/${repo}/actions/runs/${response.workflow_run_id}).`
const popupMessage = `Successfully scheduled runs on ${pluralizeRepositories(numRepositoriesQueried)}. [Click here to see the progress](https://github.com/${owner}/${repo}/actions/runs/${response.workflow_run_id}).`
+ (response.errors ? `${eol2}Some repositories could not be scheduled. See extension log for details.` : '');

let logMessage = `Successfully scheduled runs on ${numRepositoriesQueried} repositories. See https://github.com/${owner}/${repo}/actions/runs/${response.workflow_run_id}.`;
let logMessage = `Successfully scheduled runs on ${pluralizeRepositories(numRepositoriesQueried)}. See https://github.com/${owner}/${repo}/actions/runs/${response.workflow_run_id}.`;
logMessage += `${eol2}Repositories queried:${eol}${repositoriesQueried.join(', ')}`;
if (response.errors) {
const { invalid_repositories, repositories_without_database, private_repositories, cutoff_repositories, cutoff_repositories_count } = response.errors;
logMessage += `${eol2}Some repositories could not be scheduled.`;
if (invalid_repositories?.length) {
logMessage += `${eol2}${invalid_repositories.length} repositories were invalid and could not be found:${eol}${invalid_repositories.join(', ')}`;
logMessage += `${eol2}${pluralizeRepositories(invalid_repositories.length)} invalid and could not be found:${eol}${invalid_repositories.join(', ')}`;
}
if (repositories_without_database?.length) {
logMessage += `${eol2}${repositories_without_database.length} repositories did not have a CodeQL database available:${eol}${repositories_without_database.join(', ')}`;
logMessage += `${eol2}${pluralizeRepositories(repositories_without_database.length)} did not have a CodeQL database available:${eol}${repositories_without_database.join(', ')}`;
logMessage += `${eol}For each public repository that has not yet been added to the database service, we will try to create a database next time the store is updated.`;
}
if (private_repositories?.length) {
logMessage += `${eol2}${private_repositories.length} repositories are not public:${eol}${private_repositories.join(', ')}`;
logMessage += `${eol2}${pluralizeRepositories(private_repositories.length)} not public:${eol}${private_repositories.join(', ')}`;
logMessage += `${eol}When using a public controller repository, only public repositories can be queried.`;
}
if (cutoff_repositories_count) {
logMessage += `${eol2}${cutoff_repositories_count} repositories over the limit for a single request`;
logMessage += `${eol2}${pluralizeRepositories(cutoff_repositories_count)} over the limit for a single request`;
if (cutoff_repositories) {
logMessage += `:${eol}${cutoff_repositories.join(', ')}`;
if (cutoff_repositories_count !== cutoff_repositories.length) {
logMessage += `${eol}...${eol}And ${cutoff_repositories_count - cutoff_repositories.length} more repositrories.`;
logMessage += `${eol}...${eol}And ${cutoff_repositories_count - cutoff_repositories.length} more repositories.`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is right, please check my syntax (both English and Typescript).

Suggested change
logMessage += `${eol}...${eol}And ${cutoff_repositories_count - cutoff_repositories.length} more repositories.`;
const moreRepositories = cutoff_repositories_count - cutoff_repositories.length;
logMessage += `${eol}...${eol}And ${moreRepositories} more ${pluralizeRepositories(moreRepositories)}.`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, although this could print 42 more 42 repositories if we're not careful. Perhaps something like

Suggested change
logMessage += `${eol}...${eol}And ${cutoff_repositories_count - cutoff_repositories.length} more repositories.`;
const moreRepositories = cutoff_repositories_count - cutoff_repositories.length;
logMessage += `${eol}...${eol}And another ${pluralizeRepositories(moreRepositories)}.`;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good spot, thanks both! Updated in latest commit 🦒

}
} else {
logMessage += '.';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('run-remote-query', () => {
'',
'Some repositories could not be scheduled.',
'',
'2 repositories were invalid and could not be found:',
'2 repositories invalid and could not be found:',
'e/f, g/h'].join(os.EOL)
);
});
Expand Down Expand Up @@ -96,7 +96,7 @@ describe('run-remote-query', () => {
'',
'Some repositories could not be scheduled.',
'',
'2 repositories are not public:',
'2 repositories not public:',
'e/f, g/h',
'When using a public controller repository, only public repositories can be queried.'].join(os.EOL)
);
Expand Down Expand Up @@ -181,13 +181,58 @@ describe('run-remote-query', () => {
'',
'Some repositories could not be scheduled.',
'',
'2 repositories were invalid and could not be found:',
'2 repositories invalid and could not be found:',
'e/f, g/h',
'',
'2 repositories did not have a CodeQL database available:',
'i/j, k/l',
'For each public repository that has not yet been added to the database service, we will try to create a database next time the store is updated.'].join(os.EOL)
);
});

it('should parse a response with one repo of each category, and not pluralize "repositories"', () => {
const result = parseResponse('org', 'name', {
workflow_run_id: 123,
repositories_queried: ['a/b'],
errors: {
private_repositories: ['e/f'],
cutoff_repositories: ['i/j'],
cutoff_repositories_count: 1,
invalid_repositories: ['m/n'],
repositories_without_database: ['q/r'],
}
});

expect(result.popupMessage).to.equal(
['Successfully scheduled runs on 1 repository. [Click here to see the progress](https://github.com/org/name/actions/runs/123).',
'',
'Some repositories could not be scheduled. See extension log for details.'].join(os.EOL)
);
expect(result.logMessage).to.equal(
[
'Successfully scheduled runs on 1 repository. See https://github.com/org/name/actions/runs/123.',
'',
'Repositories queried:',
'a/b',
'',
'Some repositories could not be scheduled.',
'',
'1 repository invalid and could not be found:',
'm/n',
'',
'1 repository did not have a CodeQL database available:',
'q/r',
'For each public repository that has not yet been added to the database service, we will try to create a database next time the store is updated.',
'',
'1 repository not public:',
'e/f',
'When using a public controller repository, only public repositories can be queried.',
'',
'1 repository over the limit for a single request:',
'i/j',
'Repositories were selected based on how recently they had been updated.',
].join(os.EOL)
);
});
});
});