mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-25 01:41:41 +01:00
Move getting auth token into GithubCodeSearchService (#673)
This hides the implementation a bit better and should let us find the correct token for different repos
This commit is contained in:
+41
-17
@@ -14,6 +14,7 @@ import { env } from '../../../util/vs/base/common/process';
|
||||
import { URI } from '../../../util/vs/base/common/uri';
|
||||
import { Range } from '../../../util/vs/editor/common/core/range';
|
||||
import { createDecorator } from '../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { IAuthenticationService } from '../../authentication/common/authentication';
|
||||
import { FileChunkAndScore } from '../../chunking/common/chunk';
|
||||
import { getGithubMetadataHeaders } from '../../chunking/common/chunkingEndpointClientImpl';
|
||||
import { stripChunkTextMetadata, truncateToMaxUtf8Length } from '../../chunking/common/chunkingStringUtils';
|
||||
@@ -27,7 +28,7 @@ import { ILogService } from '../../log/common/logService';
|
||||
import { IFetcherService, Response } from '../../networking/common/fetcherService';
|
||||
import { postRequest } from '../../networking/common/networking';
|
||||
import { ITelemetryService } from '../../telemetry/common/telemetry';
|
||||
import { CodeSearchOptions, CodeSearchResult, RemoteCodeSearchIndexState, RemoteCodeSearchIndexStatus } from './remoteCodeSearch';
|
||||
import { CodeSearchOptions, CodeSearchResult, RemoteCodeSearchError, RemoteCodeSearchIndexState, RemoteCodeSearchIndexStatus } from './remoteCodeSearch';
|
||||
|
||||
|
||||
interface ResponseShape {
|
||||
@@ -70,16 +71,16 @@ export interface IGithubCodeSearchService {
|
||||
* Gets the state of the remote index for a given repo.
|
||||
*/
|
||||
getRemoteIndexState(
|
||||
authToken: string,
|
||||
authOptions: { readonly silent: boolean },
|
||||
githubRepoId: GithubRepoId,
|
||||
token: CancellationToken,
|
||||
): Promise<Result<RemoteCodeSearchIndexState, Error>>;
|
||||
): Promise<Result<RemoteCodeSearchIndexState, RemoteCodeSearchError>>;
|
||||
|
||||
/**
|
||||
* Requests that a given repo be indexed.
|
||||
*/
|
||||
triggerIndexing(
|
||||
authToken: string,
|
||||
authOptions: { readonly silent: boolean },
|
||||
triggerReason: 'auto' | 'manual' | 'tool',
|
||||
githubRepoId: GithubRepoId,
|
||||
telemetryInfo: TelemetryCorrelationId,
|
||||
@@ -91,7 +92,7 @@ export interface IGithubCodeSearchService {
|
||||
* The repo must have been indexed first. Make sure to check {@link getRemoteIndexState} or call {@link triggerIndexing}.
|
||||
*/
|
||||
searchRepo(
|
||||
authToken: string,
|
||||
authOptions: { readonly silent: boolean },
|
||||
embeddingType: EmbeddingType,
|
||||
repo: GithubCodeSearchRepoInfo,
|
||||
query: string,
|
||||
@@ -107,6 +108,7 @@ export class GithubCodeSearchService implements IGithubCodeSearchService {
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
constructor(
|
||||
@IAuthenticationService private readonly _authenticationService: IAuthenticationService,
|
||||
@IDomainService private readonly _domainService: IDomainService,
|
||||
@ICAPIClientService private readonly _capiClientService: ICAPIClientService,
|
||||
@IEnvService private readonly _envService: IEnvService,
|
||||
@@ -116,13 +118,19 @@ export class GithubCodeSearchService implements IGithubCodeSearchService {
|
||||
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
||||
) { }
|
||||
|
||||
async getRemoteIndexState(authToken: string, githubRepoId: GithubRepoId, token: CancellationToken): Promise<Result<RemoteCodeSearchIndexState, Error>> {
|
||||
async getRemoteIndexState(auth: { readonly silent: boolean }, githubRepoId: GithubRepoId, token: CancellationToken): Promise<Result<RemoteCodeSearchIndexState, RemoteCodeSearchError>> {
|
||||
const repoNwo = toGithubNwo(githubRepoId);
|
||||
|
||||
if (repoNwo.startsWith('microsoft/simuluation-test-')) {
|
||||
return Result.ok({ status: RemoteCodeSearchIndexStatus.NotYetIndexed });
|
||||
}
|
||||
|
||||
const authToken = await this.getGithubAccessToken(auth.silent);
|
||||
if (!authToken) {
|
||||
this._logService.error(`GithubCodeSearchService::getRemoteIndexState(${repoNwo}). Failed to fetch indexing status. No valid github auth token.`);
|
||||
return Result.error<RemoteCodeSearchError>({ type: 'not-authorized' });
|
||||
}
|
||||
|
||||
try {
|
||||
const statusRequest = await raceCancellationError(this._capiClientService.makeRequest<Response>({
|
||||
method: 'GET',
|
||||
@@ -142,14 +150,14 @@ export class GithubCodeSearchService implements IGithubCodeSearchService {
|
||||
statusCode: statusRequest.status,
|
||||
});
|
||||
|
||||
this._logService.error(`GithubCodeSearchService.getRemoteIndexState(${repoNwo}). Failed to fetch indexing status. Response: ${statusRequest.status}. ${await statusRequest.text()}`);
|
||||
return Result.error(new Error(`Failed to fetch indexing status. Response: ${statusRequest.status}.`));
|
||||
this._logService.error(`GithubCodeSearchService::getRemoteIndexState(${repoNwo}). Failed to fetch indexing status. Response: ${statusRequest.status}. ${await statusRequest.text()}`);
|
||||
return Result.error<RemoteCodeSearchError>({ type: 'generic-error', error: new Error(`Failed to fetch indexing status. Response: ${statusRequest.status}.`) });
|
||||
}
|
||||
|
||||
const preCheckResult = await raceCancellationError(statusRequest.json(), token);
|
||||
if (preCheckResult.semantic_code_search_ok && preCheckResult.semantic_commit_sha) {
|
||||
const indexedCommit = preCheckResult.semantic_commit_sha;
|
||||
this._logService.trace(`GithubCodeSearchService.getRemoteIndexState(${repoNwo}). Found indexed commit: ${indexedCommit}.`);
|
||||
this._logService.trace(`GithubCodeSearchService::getRemoteIndexState(${repoNwo}). Found indexed commit: ${indexedCommit}.`);
|
||||
return Result.ok({
|
||||
status: RemoteCodeSearchIndexStatus.Ready,
|
||||
indexedCommit,
|
||||
@@ -158,36 +166,41 @@ export class GithubCodeSearchService implements IGithubCodeSearchService {
|
||||
|
||||
if (preCheckResult.semantic_indexing_enabled) {
|
||||
if (await raceCancellationError(this.isEmptyRepo(authToken, githubRepoId, token), token)) {
|
||||
this._logService.trace(`GithubCodeSearchService.getRemoteIndexState(${repoNwo}). Semantic indexing enabled but repo is empty.`);
|
||||
this._logService.trace(`GithubCodeSearchService::getRemoteIndexState(${repoNwo}). Semantic indexing enabled but repo is empty.`);
|
||||
return Result.ok({
|
||||
status: RemoteCodeSearchIndexStatus.Ready,
|
||||
indexedCommit: undefined
|
||||
});
|
||||
}
|
||||
|
||||
this._logService.trace(`GithubCodeSearchService.getRemoteIndexState(${repoNwo}). Semantic indexing enabled but not yet indexed.`);
|
||||
this._logService.trace(`GithubCodeSearchService::getRemoteIndexState(${repoNwo}). Semantic indexing enabled but not yet indexed.`);
|
||||
|
||||
return Result.ok({ status: RemoteCodeSearchIndexStatus.BuildingIndex });
|
||||
} else {
|
||||
this._logService.trace(`GithubCodeSearchService.getRemoteIndexState(${repoNwo}). semantic_indexing_enabled was false. Repo not yet indexed but possibly can be.`);
|
||||
this._logService.trace(`GithubCodeSearchService::getRemoteIndexState(${repoNwo}). semantic_indexing_enabled was false. Repo not yet indexed but possibly can be.`);
|
||||
return Result.ok({ status: RemoteCodeSearchIndexStatus.NotYetIndexed });
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e: unknown) {
|
||||
if (isCancellationError(e)) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
this._logService.error(`GithubCodeSearchService.getRemoteIndexState(${repoNwo}). Error: ${e}`);
|
||||
return Result.error(e);
|
||||
this._logService.error(`GithubCodeSearchService::getRemoteIndexState(${repoNwo}). Error: ${e}`);
|
||||
return Result.error<RemoteCodeSearchError>({ type: 'generic-error', error: e instanceof Error ? e : new Error(String(e)) });
|
||||
}
|
||||
}
|
||||
|
||||
public async triggerIndexing(
|
||||
authToken: string,
|
||||
auth: { readonly silent: boolean },
|
||||
triggerReason: 'auto' | 'manual' | 'tool',
|
||||
githubRepoId: GithubRepoId,
|
||||
telemetryInfo: TelemetryCorrelationId,
|
||||
): Promise<boolean> {
|
||||
const authToken = await this.getGithubAccessToken(auth.silent);
|
||||
if (!authToken) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const response = await this._capiClientService.makeRequest<Response>({
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -241,7 +254,7 @@ export class GithubCodeSearchService implements IGithubCodeSearchService {
|
||||
}
|
||||
|
||||
async searchRepo(
|
||||
authToken: string,
|
||||
auth: { readonly silent: boolean },
|
||||
embeddingType: EmbeddingType,
|
||||
repo: GithubCodeSearchRepoInfo,
|
||||
searchQuery: string,
|
||||
@@ -250,6 +263,11 @@ export class GithubCodeSearchService implements IGithubCodeSearchService {
|
||||
telemetryInfo: TelemetryCorrelationId,
|
||||
token: CancellationToken
|
||||
): Promise<CodeSearchResult> {
|
||||
const authToken = await this.getGithubAccessToken(auth.silent);
|
||||
if (!authToken) {
|
||||
throw new Error('No valid auth token');
|
||||
}
|
||||
|
||||
const response = await raceCancellationError(
|
||||
postRequest(
|
||||
this._fetcherService,
|
||||
@@ -330,6 +348,12 @@ export class GithubCodeSearchService implements IGithubCodeSearchService {
|
||||
return result;
|
||||
}
|
||||
|
||||
private async getGithubAccessToken(silent: boolean) {
|
||||
return (await this._authenticationService.getPermissiveGitHubSession({ silent }))?.accessToken
|
||||
?? (await this._authenticationService.getAnyGitHubSession({ silent }))?.accessToken;
|
||||
}
|
||||
|
||||
|
||||
private async isEmptyRepo(authToken: string, githubRepoId: GithubRepoId, token: CancellationToken): Promise<boolean> {
|
||||
const response = await raceCancellationError(fetch(this._capiClientService.dotcomAPIURL + `/repos/${toGithubNwo(githubRepoId)}`, {
|
||||
headers: {
|
||||
|
||||
Reference in New Issue
Block a user