mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-24 01:25:37 -05:00
Merge from vscode merge-base (#22780)
* Revert "Revert "Merge from vscode merge-base (#22769)" (#22779)"
This reverts commit 47a1745180.
* Fix notebook download task
* Remove done call from extensions-ci
This commit is contained in:
@@ -3,22 +3,23 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, OutputChannel, commands } from 'vscode';
|
||||
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, commands } from 'vscode';
|
||||
import TelemetryReporter from '@vscode/extension-telemetry';
|
||||
import { Repository, RepositoryState } from './repository';
|
||||
import { memoize, sequentialize, debounce } from './decorators';
|
||||
import { dispose, anyEvent, filterEvent, isDescendant, pathEquals, toDisposable, eventToPromise, logTimestamp } from './util';
|
||||
import { dispose, anyEvent, filterEvent, isDescendant, pathEquals, toDisposable, eventToPromise } from './util';
|
||||
import { Git } from './git';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { fromGitUri } from './uri';
|
||||
import { APIState as State, CredentialsProvider, PushErrorHandler, PublishEvent, RemoteSourcePublisher } from './api/git';
|
||||
import { APIState as State, CredentialsProvider, PushErrorHandler, PublishEvent, RemoteSourcePublisher, PostCommitCommandsProvider } from './api/git';
|
||||
import { Askpass } from './askpass';
|
||||
import { IPushErrorHandlerRegistry } from './pushError';
|
||||
import { ApiRepository } from './api/api1';
|
||||
import { IRemoteSourcePublisherRegistry } from './remotePublisher';
|
||||
import { Log, LogLevel } from './log';
|
||||
import { OutputChannelLogger } from './log';
|
||||
import { IPostCommitCommandsProviderRegistry } from './postCommitCommands';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -50,7 +51,7 @@ interface OpenRepository extends Disposable {
|
||||
repository: Repository;
|
||||
}
|
||||
|
||||
export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerRegistry {
|
||||
export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommandsProviderRegistry, IPushErrorHandlerRegistry {
|
||||
|
||||
private _onDidOpenRepository = new EventEmitter<Repository>();
|
||||
readonly onDidOpenRepository: Event<Repository> = this._onDidOpenRepository.event;
|
||||
@@ -105,12 +106,17 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
private _onDidRemoveRemoteSourcePublisher = new EventEmitter<RemoteSourcePublisher>();
|
||||
readonly onDidRemoveRemoteSourcePublisher = this._onDidRemoveRemoteSourcePublisher.event;
|
||||
|
||||
private postCommitCommandsProviders = new Set<PostCommitCommandsProvider>();
|
||||
|
||||
private _onDidChangePostCommitCommandsProviders = new EventEmitter<void>();
|
||||
readonly onDidChangePostCommitCommandsProviders = this._onDidChangePostCommitCommandsProviders.event;
|
||||
|
||||
private showRepoOnHomeDriveRootWarning = true;
|
||||
private pushErrorHandlers = new Set<PushErrorHandler>();
|
||||
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(readonly git: Git, private readonly askpass: Askpass, private globalState: Memento, private outputChannel: OutputChannel, private telemetryReporter: TelemetryReporter) {
|
||||
constructor(readonly git: Git, private readonly askpass: Askpass, private globalState: Memento, private outputChannelLogger: OutputChannelLogger, private telemetryReporter: TelemetryReporter) {
|
||||
workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, this.disposables);
|
||||
window.onDidChangeVisibleTextEditors(this.onDidChangeVisibleTextEditors, this, this.disposables);
|
||||
workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.disposables);
|
||||
@@ -143,11 +149,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
private async scanWorkspaceFolders(): Promise<void> {
|
||||
const config = workspace.getConfiguration('git');
|
||||
const autoRepositoryDetection = config.get<boolean | 'subFolders' | 'openEditors'>('autoRepositoryDetection');
|
||||
|
||||
// Log repository scan settings
|
||||
if (Log.logLevel <= LogLevel.Trace) {
|
||||
this.outputChannel.appendLine(`${logTimestamp()} Trace: autoRepositoryDetection="${autoRepositoryDetection}"`);
|
||||
}
|
||||
this.outputChannelLogger.logTrace(`[swsf] Scan workspace sub folders. autoRepositoryDetection=${autoRepositoryDetection}`);
|
||||
|
||||
if (autoRepositoryDetection !== true && autoRepositoryDetection !== 'subFolders') {
|
||||
return;
|
||||
@@ -155,6 +157,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
|
||||
await Promise.all((workspace.workspaceFolders || []).map(async folder => {
|
||||
const root = folder.uri.fsPath;
|
||||
this.outputChannelLogger.logTrace(`[swsf] Workspace folder: ${root}`);
|
||||
|
||||
// Workspace folder children
|
||||
const repositoryScanMaxDepth = (workspace.isTrusted ? workspace.getConfiguration('git', folder.uri) : config).get<number>('repositoryScanMaxDepth', 1);
|
||||
@@ -164,19 +167,25 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
|
||||
// Repository scan folders
|
||||
const scanPaths = (workspace.isTrusted ? workspace.getConfiguration('git', folder.uri) : config).get<string[]>('scanRepositories') || [];
|
||||
this.outputChannelLogger.logTrace(`[swsf] Workspace scan settings: repositoryScanMaxDepth=${repositoryScanMaxDepth}; repositoryScanIgnoredFolders=[${repositoryScanIgnoredFolders.join(', ')}]; scanRepositories=[${scanPaths.join(', ')}]`);
|
||||
|
||||
for (const scanPath of scanPaths) {
|
||||
if (scanPath === '.git') {
|
||||
this.outputChannelLogger.logTrace('[swsf] \'.git\' not supported in \'git.scanRepositories\' setting.');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (path.isAbsolute(scanPath)) {
|
||||
console.warn(localize('not supported', "Absolute paths not supported in 'git.scanRepositories' setting."));
|
||||
const notSupportedMessage = localize('not supported', "Absolute paths not supported in 'git.scanRepositories' setting.");
|
||||
this.outputChannelLogger.logWarning(notSupportedMessage);
|
||||
console.warn(notSupportedMessage);
|
||||
continue;
|
||||
}
|
||||
|
||||
subfolders.add(path.join(root, scanPath));
|
||||
}
|
||||
|
||||
this.outputChannelLogger.logTrace(`[swsf] Workspace scan sub folders: [${[...subfolders].join(', ')}]`);
|
||||
await Promise.all([...subfolders].map(f => this.openRepository(f)));
|
||||
}));
|
||||
}
|
||||
@@ -247,6 +256,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
.filter(r => !(workspace.workspaceFolders || []).some(f => isDescendant(f.uri.fsPath, r!.repository.root))) as OpenRepository[];
|
||||
|
||||
openRepositoriesToDispose.forEach(r => r.dispose());
|
||||
this.outputChannelLogger.logTrace(`[swf] Scan workspace folders: [${possibleRepositoryFolders.map(p => p.uri.fsPath).join(', ')}]`);
|
||||
await Promise.all(possibleRepositoryFolders.map(p => this.openRepository(p.uri.fsPath)));
|
||||
}
|
||||
|
||||
@@ -260,17 +270,20 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
.filter(({ root }) => workspace.getConfiguration('git', root).get<boolean>('enabled') !== true)
|
||||
.map(({ repository }) => repository);
|
||||
|
||||
this.outputChannelLogger.logTrace(`[swf] Scan workspace folders: [${possibleRepositoryFolders.map(p => p.uri.fsPath).join(', ')}]`);
|
||||
possibleRepositoryFolders.forEach(p => this.openRepository(p.uri.fsPath));
|
||||
openRepositoriesToDispose.forEach(r => r.dispose());
|
||||
}
|
||||
|
||||
private async onDidChangeVisibleTextEditors(editors: readonly TextEditor[]): Promise<void> {
|
||||
if (!workspace.isTrusted) {
|
||||
this.outputChannelLogger.logTrace('[svte] Workspace is not trusted.');
|
||||
return;
|
||||
}
|
||||
|
||||
const config = workspace.getConfiguration('git');
|
||||
const autoRepositoryDetection = config.get<boolean | 'subFolders' | 'openEditors'>('autoRepositoryDetection');
|
||||
this.outputChannelLogger.logTrace(`[svte] Scan visible text editors. autoRepositoryDetection=${autoRepositoryDetection}`);
|
||||
|
||||
if (autoRepositoryDetection !== true && autoRepositoryDetection !== 'openEditors') {
|
||||
return;
|
||||
@@ -286,16 +299,20 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
const repository = this.getRepository(uri);
|
||||
|
||||
if (repository) {
|
||||
this.outputChannelLogger.logTrace(`[svte] Repository for editor resource ${uri.fsPath} already exists: ${repository.root}`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.outputChannelLogger.logTrace(`[svte] Open repository for editor resource ${uri.fsPath}`);
|
||||
await this.openRepository(path.dirname(uri.fsPath));
|
||||
}));
|
||||
}
|
||||
|
||||
@sequentialize
|
||||
async openRepository(repoPath: string): Promise<void> {
|
||||
this.outputChannelLogger.logTrace(`Opening repository: ${repoPath}`);
|
||||
if (this.getRepository(repoPath)) {
|
||||
this.outputChannelLogger.logTrace(`Repository for path ${repoPath} already exists`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -303,6 +320,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
const enabled = config.get<boolean>('enabled') === true;
|
||||
|
||||
if (!enabled) {
|
||||
this.outputChannelLogger.logTrace('Git is not enabled');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -312,6 +330,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
fs.accessSync(path.join(repoPath, 'HEAD'), fs.constants.F_OK);
|
||||
const result = await this.git.exec(repoPath, ['-C', repoPath, 'rev-parse', '--show-cdup']);
|
||||
if (result.stderr.trim() === '' && result.stdout.trim() === '') {
|
||||
this.outputChannelLogger.logTrace(`Bare repository: ${repoPath}`);
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
@@ -326,12 +345,15 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
// case insensitive file systems
|
||||
// https://github.com/microsoft/vscode/issues/33498
|
||||
const repositoryRoot = Uri.file(rawRoot).fsPath;
|
||||
this.outputChannelLogger.logTrace(`Repository root: ${repositoryRoot}`);
|
||||
|
||||
if (this.getRepository(repositoryRoot)) {
|
||||
this.outputChannelLogger.logTrace(`Repository for path ${repositoryRoot} already exists`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.shouldRepositoryBeIgnored(rawRoot)) {
|
||||
this.outputChannelLogger.logTrace(`Repository for path ${repositoryRoot} is ignored`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -347,20 +369,19 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
this.showRepoOnHomeDriveRootWarning = false;
|
||||
}
|
||||
|
||||
this.outputChannelLogger.logTrace(`Repository for path ${repositoryRoot} is on the root of the HOMEDRIVE`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const dotGit = await this.git.getRepositoryDotGit(repositoryRoot);
|
||||
const repository = new Repository(this.git.open(repositoryRoot, dotGit), this, this, this.globalState, this.outputChannel, this.telemetryReporter);
|
||||
const repository = new Repository(this.git.open(repositoryRoot, dotGit), this, this, this, this.globalState, this.outputChannelLogger, this.telemetryReporter);
|
||||
|
||||
this.open(repository);
|
||||
repository.status(); // do not await this, we want SCM to know about the repo asap
|
||||
} catch (ex) {
|
||||
// noop
|
||||
if (Log.logLevel <= LogLevel.Trace) {
|
||||
this.outputChannel.appendLine(`${logTimestamp()} Trace: Opening repository for path='${repoPath}' failed; ex=${ex}`);
|
||||
}
|
||||
this.outputChannelLogger.logTrace(`Opening repository for path='${repoPath}' failed; ex=${ex}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +407,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
}
|
||||
|
||||
private open(repository: Repository): void {
|
||||
this.outputChannel.appendLine(`${logTimestamp()} Open repository: ${repository.root}`);
|
||||
this.outputChannelLogger.logInfo(`Open repository: ${repository.root}`);
|
||||
|
||||
const onDidDisappearRepository = filterEvent(repository.onDidChangeState, state => state === RepositoryState.Disposed);
|
||||
const disappearListener = onDidDisappearRepository(() => dispose());
|
||||
@@ -443,7 +464,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
return;
|
||||
}
|
||||
|
||||
this.outputChannel.appendLine(`${logTimestamp()} Close repository: ${repository.root}`);
|
||||
this.outputChannelLogger.logInfo(`Close repository: ${repository.root}`);
|
||||
openRepository.dispose();
|
||||
}
|
||||
|
||||
@@ -491,6 +512,10 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
return this.openRepositories.filter(r => r.repository === hint)[0];
|
||||
}
|
||||
|
||||
if (hint instanceof ApiRepository) {
|
||||
return this.openRepositories.filter(r => r.repository === hint.repository)[0];
|
||||
}
|
||||
|
||||
if (typeof hint === 'string') {
|
||||
hint = Uri.file(hint);
|
||||
}
|
||||
@@ -567,6 +592,20 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
return [...this.remoteSourcePublishers.values()];
|
||||
}
|
||||
|
||||
registerPostCommitCommandsProvider(provider: PostCommitCommandsProvider): Disposable {
|
||||
this.postCommitCommandsProviders.add(provider);
|
||||
this._onDidChangePostCommitCommandsProviders.fire();
|
||||
|
||||
return toDisposable(() => {
|
||||
this.postCommitCommandsProviders.delete(provider);
|
||||
this._onDidChangePostCommitCommandsProviders.fire();
|
||||
});
|
||||
}
|
||||
|
||||
getPostCommitCommandsProviders(): PostCommitCommandsProvider[] {
|
||||
return [...this.postCommitCommandsProviders.values()];
|
||||
}
|
||||
|
||||
registerCredentialsProvider(provider: CredentialsProvider): Disposable {
|
||||
return this.askpass.registerCredentialsProvider(provider);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user