Files
azuredatastudio/extensions/git/src/main.ts
Karl Burtram 8a3d08f0de Merge vscode 1.67 (#20883)
* Fix initial build breaks from 1.67 merge (#2514)

* Update yarn lock files

* Update build scripts

* Fix tsconfig

* Build breaks

* WIP

* Update yarn lock files

* Misc breaks

* Updates to package.json

* Breaks

* Update yarn

* Fix breaks

* Breaks

* Build breaks

* Breaks

* Breaks

* Breaks

* Breaks

* Breaks

* Missing file

* Breaks

* Breaks

* Breaks

* Breaks

* Breaks

* Fix several runtime breaks (#2515)

* Missing files

* Runtime breaks

* Fix proxy ordering issue

* Remove commented code

* Fix breaks with opening query editor

* Fix post merge break

* Updates related to setup build and other breaks (#2516)

* Fix bundle build issues

* Update distro

* Fix distro merge and update build JS files

* Disable pipeline steps

* Remove stats call

* Update license name

* Make new RPM dependencies a warning

* Fix extension manager version checks

* Update JS file

* Fix a few runtime breaks

* Fixes

* Fix runtime issues

* Fix build breaks

* Update notebook tests (part 1)

* Fix broken tests

* Linting errors

* Fix hygiene

* Disable lint rules

* Bump distro

* Turn off smoke tests

* Disable integration tests

* Remove failing "activate" test

* Remove failed test assertion

* Disable other broken test

* Disable query history tests

* Disable extension unit tests

* Disable failing tasks
2022-10-19 19:13:18 -07:00

222 lines
7.9 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { ExtensionContext, workspace, window, Disposable, commands, OutputChannel } from 'vscode';
import { findGit, Git } from './git';
import { Model } from './model';
import { CommandCenter } from './commands';
import { GitFileSystemProvider } from './fileSystemProvider';
import { GitDecorations } from './decorationProvider';
import { Askpass } from './askpass';
import { toDisposable, filterEvent, eventToPromise, logTimestamp } from './util';
import TelemetryReporter from '@vscode/extension-telemetry';
import { GitExtension } from './api/git';
import { GitProtocolHandler } from './protocolHandler';
import { GitExtensionImpl } from './api/extension';
import * as path from 'path';
// import * as fs from 'fs';
import * as os from 'os';
import { GitTimelineProvider } from './timelineProvider';
import { registerAPICommands } from './api/api1';
import { TerminalEnvironmentManager } from './terminal';
const deactivateTasks: { (): Promise<any> }[] = [];
export async function deactivate(): Promise<any> {
for (const task of deactivateTasks) {
await task();
}
}
async function createModel(context: ExtensionContext, outputChannel: OutputChannel, telemetryReporter: TelemetryReporter, disposables: Disposable[]): Promise<Model> {
const pathValue = workspace.getConfiguration('git').get<string | string[]>('path');
let pathHints = Array.isArray(pathValue) ? pathValue : pathValue ? [pathValue] : [];
const { isTrusted, workspaceFolders = [] } = workspace;
const excludes = isTrusted ? [] : workspaceFolders.map(f => path.normalize(f.uri.fsPath).replace(/[\r\n]+$/, ''));
if (!isTrusted && pathHints.length !== 0) {
// Filter out any non-absolute paths
pathHints = pathHints.filter(p => path.isAbsolute(p));
}
const info = await findGit(pathHints, gitPath => {
outputChannel.appendLine(localize('validating', "{0} Validating found git in: {1}", logTimestamp(), gitPath));
if (excludes.length === 0) {
return true;
}
const normalized = path.normalize(gitPath).replace(/[\r\n]+$/, '');
const skip = excludes.some(e => normalized.startsWith(e));
if (skip) {
outputChannel.appendLine(localize('skipped', "{0} Skipped found git in: {1}", logTimestamp(), gitPath));
}
return !skip;
});
const askpass = await Askpass.create(outputChannel, context.storagePath);
disposables.push(askpass);
const environment = askpass.getEnv();
const terminalEnvironmentManager = new TerminalEnvironmentManager(context, environment);
disposables.push(terminalEnvironmentManager);
const git = new Git({
gitPath: info.path,
userAgent: `git/${info.version} (${(os as any).version?.() ?? os.type()} ${os.release()}; ${os.platform()} ${os.arch()}) azuredatudio`,
version: info.version,
env: environment,
});
const model = new Model(git, askpass, context.globalState, outputChannel, telemetryReporter);
disposables.push(model);
const onRepository = () => commands.executeCommand('setContext', 'gitOpenRepositoryCount', `${model.repositories.length}`);
model.onDidOpenRepository(onRepository, null, disposables);
model.onDidCloseRepository(onRepository, null, disposables);
onRepository();
outputChannel.appendLine(localize('using git', "{0} Using git {1} from {2}", logTimestamp(), info.version, info.path));
const onOutput = (str: string) => {
const lines = str.split(/\r?\n/mg);
while (/^\s*$/.test(lines[lines.length - 1])) {
lines.pop();
}
outputChannel.appendLine(`${logTimestamp()} ${lines.join('\n')}`);
};
git.onOutput.addListener('log', onOutput);
disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput)));
const cc = new CommandCenter(git, model, outputChannel, telemetryReporter);
disposables.push(
cc,
new GitFileSystemProvider(model),
new GitDecorations(model),
new GitProtocolHandler(),
new GitTimelineProvider(model, cc)
);
// checkGitVersion(info); {{SQL CARBON EDIT}} Don't check git version
return model;
}
/* {{SQL CARBON EDIT}} - Comment out function that is unused due to our edit below
async function isGitRepository(folder: WorkspaceFolder): Promise<boolean> {
if (folder.uri.scheme !== 'file') {
return false;
}
const dotGit = path.join(folder.uri.fsPath, '.git');
try {
const dotGitStat = await new Promise<fs.Stats>((c, e) => fs.stat(dotGit, (err, stat) => err ? e(err) : c(stat)));
return dotGitStat.isDirectory();
} catch (err) {
return false;
}
}
async function warnAboutMissingGit(): Promise<void> {
const config = workspace.getConfiguration('git');
const shouldIgnore = config.get<boolean>('ignoreMissingGitWarning') === true;
if (shouldIgnore) {
return;
}
if (!workspace.workspaceFolders) {
return;
}
const areGitRepositories = await Promise.all(workspace.workspaceFolders.map(isGitRepository));
if (areGitRepositories.every(isGitRepository => !isGitRepository)) {
return;
}
const download = localize('downloadgit', "Download Git");
const neverShowAgain = localize('neverShowAgain', "Don't Show Again");
const choice = await window.showWarningMessage(
localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."),
download,
neverShowAgain
);
if (choice === download) {
commands.executeCommand('vscode.open', Uri.parse('https://aka.ms/vscode-download-git'));
} else if (choice === neverShowAgain) {
await config.update('ignoreMissingGitWarning', true, true);
}
}*/
export async function _activate(context: ExtensionContext): Promise<GitExtensionImpl> {
const disposables: Disposable[] = [];
context.subscriptions.push(new Disposable(() => Disposable.from(...disposables).dispose()));
const outputChannel = window.createOutputChannel('Git');
commands.registerCommand('git.showOutput', () => outputChannel.show());
disposables.push(outputChannel);
const { name, version, aiKey } = require('../package.json') as { name: string; version: string; aiKey: string };
const telemetryReporter = new TelemetryReporter(name, version, aiKey);
deactivateTasks.push(() => telemetryReporter.dispose());
const config = workspace.getConfiguration('git', null);
const enabled = config.get<boolean>('enabled');
if (!enabled) {
const onConfigChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git'));
const onEnabled = filterEvent(onConfigChange, () => workspace.getConfiguration('git', null).get<boolean>('enabled') === true);
const result = new GitExtensionImpl();
eventToPromise(onEnabled).then(async () => result.model = await createModel(context, outputChannel, telemetryReporter, disposables));
return result;
}
try {
const model = await createModel(context, outputChannel, telemetryReporter, disposables);
return new GitExtensionImpl(model);
} catch (err) {
if (!/Git installation not found/.test(err.message || '')) {
throw err;
}
// console.warn(err.message); {{SQL CARBON EDIT}} turn-off Git missing prompt
// outputChannel.appendLine(err.message); {{SQL CARBON EDIT}} turn-off Git missing prompt
/* __GDPR__
"git.missing" : {}
*/
telemetryReporter.sendTelemetryEvent('git.missing');
commands.executeCommand('setContext', 'git.missing', true);
// warnAboutMissingGit(); {{SQL CARBON EDIT}} turn-off Git missing prompt
return new GitExtensionImpl();
}
}
let _context: ExtensionContext;
export function getExtensionContext(): ExtensionContext {
return _context;
}
export async function activate(context: ExtensionContext): Promise<GitExtension> {
_context = context;
const result = await _activate(context);
context.subscriptions.push(registerAPICommands(result));
return result;
}
// {{SQL CARBON EDIT}} - delete unneeded functions at end of file