Browse Source

Adds @me support to commit search

- @me automatically searches for commits authored by the current user
Allows (strips) `@`-prefix for author search on non-virtual repos
main
Eric Amodio 2 years ago
parent
commit
af29012b47
3 changed files with 94 additions and 78 deletions
  1. +7
    -3
      src/env/node/git/localGitProvider.ts
  2. +17
    -2
      src/git/search.ts
  3. +70
    -73
      src/plus/github/githubGitProvider.ts

+ 7
- 3
src/env/node/git/localGitProvider.ts View File

@ -4242,7 +4242,9 @@ export class LocalGitProvider implements GitProvider, Disposable {
const limit = options?.limit ?? configuration.get('advanced.maxSearchItems') ?? 0;
const similarityThreshold = configuration.get('advanced.similarityThreshold');
const { args, files, shas } = getGitArgsFromSearchQuery(search);
const currentUser = await this.getCurrentUser(repoPath);
const { args, files, shas } = getGitArgsFromSearchQuery(search, currentUser);
args.push(`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`, '--');
if (files.length !== 0) {
@ -4262,7 +4264,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
repoPath,
undefined,
undefined,
await this.getCurrentUser(repoPath),
currentUser,
limit,
false,
undefined,
@ -4334,7 +4336,9 @@ export class LocalGitProvider implements GitProvider, Disposable {
try {
const refAndDateParser = getRefAndDateParser();
const { args: searchArgs, files, shas } = getGitArgsFromSearchQuery(search);
const currentUser = search.query.includes('@me') ? await this.getCurrentUser(repoPath) : undefined;
const { args: searchArgs, files, shas } = getGitArgsFromSearchQuery(search, currentUser);
if (shas?.size) {
const data = await this.git.show2(
repoPath,

+ 17
- 2
src/git/search.ts View File

@ -1,5 +1,6 @@
import type { GitRevisionReference } from './models/reference';
import { GitRevision } from './models/reference';
import type { GitUser } from './models/user';
export type SearchOperators =
| ''
@ -132,7 +133,7 @@ export function parseSearchQuery(search: SearchQuery): Map {
({ value, text } = match.groups);
if (text) {
op = GitRevision.isSha(text) ? 'commit:' : 'message:';
op = text === '@me' ? 'author:' : GitRevision.isSha(text) ? 'commit:' : 'message:';
value = text;
}
@ -151,7 +152,10 @@ export function parseSearchQuery(search: SearchQuery): Map {
const doubleQuoteRegex = /"/g;
export function getGitArgsFromSearchQuery(search: SearchQuery): {
export function getGitArgsFromSearchQuery(
search: SearchQuery,
currentUser: GitUser | undefined,
): {
args: string[];
files: string[];
shas?: Set<string> | undefined;
@ -199,6 +203,17 @@ export function getGitArgsFromSearchQuery(search: SearchQuery): {
value = value.replace(doubleQuoteRegex, search.matchRegex ? '\b' : '');
if (!value) continue;
if (value === '@me') {
if (currentUser?.name == null) continue;
value = currentUser.name;
}
if (value.startsWith('@')) {
searchArgs.add(`--author=${value.slice(1)}`);
continue;
}
searchArgs.add(`--author=${value}`);
}

+ 70
- 73
src/plus/github/githubGitProvider.ts View File

@ -2563,8 +2563,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
const operations = parseSearchQuery(search);
let op;
let values = operations.get('commit:');
const values = operations.get('commit:');
if (values != null) {
const commit = await this.getCommit(repoPath, values[0]);
if (commit == null) return undefined;
@ -2580,53 +2579,26 @@ export class GitHubGitProvider implements GitProvider, Disposable {
};
}
const query = [];
for ([op, values] of operations.entries()) {
switch (op) {
case 'message:':
query.push(...values.map(m => m.replace(/ /g, '+')));
break;
case 'author:':
query.push(
...values.map(a => {
a = a.replace(/ /g, '+');
if (a.startsWith('@')) return `author:${a.slice(1)}`;
if (a.startsWith('"@')) return `author:"${a.slice(2)}`;
if (a.includes('@')) return `author-email:${a}`;
return `author-name:${a}`;
}),
);
break;
// case 'change:':
// case 'file:':
// break;
}
}
if (query.length === 0) return undefined;
const queryArgs = await this.getQueryArgsFromSearchQuery(search, operations, repoPath);
if (queryArgs.length === 0) return undefined;
const limit = this.getPagingLimit(options?.limit);
try {
const { metadata, github, session } = await this.ensureRepositoryContext(repoPath);
const result = await github.searchCommits(
session.accessToken,
`repo:${metadata.repo.owner}/${metadata.repo.name}+${query.join('+').trim()}`,
{
cursor: options?.cursor,
limit: limit,
sort:
options?.ordering === 'date'
? 'committer-date'
: options?.ordering === 'author-date'
? 'author-date'
: undefined,
},
);
const query = `repo:${metadata.repo.owner}/${metadata.repo.name}+${queryArgs.join('+').trim()}`;
const result = await github.searchCommits(session.accessToken, query, {
cursor: options?.cursor,
limit: limit,
sort:
options?.ordering === 'date'
? 'committer-date'
: options?.ordering === 'author-date'
? 'author-date'
: undefined,
});
if (result == null) return undefined;
const commits = new Map<string, GitCommit>();
@ -2760,8 +2732,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
const results: GitSearchResults = new Map<string, GitSearchResultData>();
const operations = parseSearchQuery(search);
let op;
let values = operations.get('commit:');
const values = operations.get('commit:');
if (values != null) {
const commitsResults = await Promise.allSettled<Promise<GitCommit | undefined>[]>(
values.map(v => this.getCommit(repoPath, v.replace(doubleQuoteRegex, ''))),
@ -2786,33 +2757,8 @@ export class GitHubGitProvider implements GitProvider, Disposable {
};
}
const queryValues: string[] = [];
for ([op, values] of operations.entries()) {
switch (op) {
case 'message:':
queryValues.push(...values.map(m => m.replace(/ /g, '+')));
break;
case 'author:':
queryValues.push(
...values.map(a => {
a = a.replace(/ /g, '+');
if (a.startsWith('@')) return `author:${a.slice(1)}`;
if (a.startsWith('"@')) return `author:"${a.slice(2)}`;
if (a.includes('@')) return `author-email:${a}`;
return `author-name:${a}`;
}),
);
break;
// case 'change:':
// case 'file:':
// break;
}
}
if (queryValues.length === 0) {
const queryArgs = await this.getQueryArgsFromSearchQuery(search, operations, repoPath);
if (queryArgs.length === 0) {
return {
repoPath: repoPath,
query: search,
@ -2823,7 +2769,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
const { metadata, github, session } = await this.ensureRepositoryContext(repoPath);
const query = `repo:${metadata.repo.owner}/${metadata.repo.name}+${queryValues.join('+').trim()}`;
const query = `repo:${metadata.repo.owner}/${metadata.repo.name}+${queryArgs.join('+').trim()}`;
async function searchForCommitsCore(
this: GitHubGitProvider,
@ -3182,6 +3128,57 @@ export class GitHubGitProvider implements GitProvider, Disposable {
return ref;
}
private async getQueryArgsFromSearchQuery(
search: SearchQuery,
operations: Map<string, string[]>,
repoPath: string,
) {
const query = [];
for (const [op, values] of operations.entries()) {
switch (op) {
case 'message:':
query.push(...values.map(m => m.replace(/ /g, '+')));
break;
case 'author:': {
let currentUser: GitUser | undefined;
if (values.includes('@me')) {
currentUser = await this.getCurrentUser(repoPath);
}
for (let value of values) {
if (!value) continue;
value = value.replace(doubleQuoteRegex, search.matchRegex ? '\b' : '');
if (!value) continue;
if (value === '@me') {
if (currentUser?.username == null) continue;
value = `@${currentUser.username}`;
}
value = value.replace(/ /g, '+');
if (value.startsWith('@')) {
query.push(`author:${value.slice(1)}`);
} else if (value.includes('@')) {
query.push(`author-email:${value}`);
} else {
query.push(`author-name:${value}`);
}
}
break;
}
// case 'change:':
// case 'file:':
// break;
}
}
return query;
}
}
function encodeAuthority<T>(scheme: string, metadata?: T): string {

||||||
x
 
000:0
Loading…
Cancel
Save