mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-08 01:28:26 -05:00
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
This commit is contained in:
7
extensions/git-base/.vscodeignore
Normal file
7
extensions/git-base/.vscodeignore
Normal file
@@ -0,0 +1,7 @@
|
||||
src/**
|
||||
build/**
|
||||
cgmanifest.json
|
||||
extension.webpack.config.js
|
||||
extension-browser.webpack.config.js
|
||||
tsconfig.json
|
||||
|
||||
20
extensions/git-base/README.md
Normal file
20
extensions/git-base/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Git static contributions and remote repository picker
|
||||
|
||||
**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.
|
||||
|
||||
## Features
|
||||
|
||||
Git static contributions and remote repository picker.
|
||||
|
||||
## API
|
||||
|
||||
The Git extension exposes an API, reachable by any other extension.
|
||||
|
||||
1. Copy `src/api/git-base.d.ts` to your extension's sources;
|
||||
2. Include `git-base.d.ts` in your extension's compilation.
|
||||
3. Get a hold of the API with the following snippet:
|
||||
|
||||
```ts
|
||||
const gitBaseExtension = vscode.extensions.getExtension<GitBaseExtension>('vscode.git-base').exports;
|
||||
const git = gitBaseExtension.getAPI(1);
|
||||
```
|
||||
10
extensions/git-base/build/update-grammars.js
Normal file
10
extensions/git-base/build/update-grammars.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
var updateGrammar = require('vscode-grammar-updater');
|
||||
|
||||
updateGrammar.update('textmate/git.tmbundle', 'Syntaxes/Git%20Commit%20Message.tmLanguage', './syntaxes/git-commit.tmLanguage.json');
|
||||
updateGrammar.update('textmate/git.tmbundle', 'Syntaxes/Git%20Rebase%20Message.tmLanguage', './syntaxes/git-rebase.tmLanguage.json');
|
||||
39
extensions/git-base/cgmanifest.json
Normal file
39
extensions/git-base/cgmanifest.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"registrations": [
|
||||
{
|
||||
"component": {
|
||||
"type": "git",
|
||||
"git": {
|
||||
"name": "textmate/git.tmbundle",
|
||||
"repositoryUrl": "https://github.com/textmate/git.tmbundle",
|
||||
"commitHash": "5870cf3f8abad3a6637bdf69250b5d2ded427dc4"
|
||||
}
|
||||
},
|
||||
"licenseDetail": [
|
||||
"Copyright (c) 2008 Tim Harper",
|
||||
"",
|
||||
"Permission is hereby granted, free of charge, to any person obtaining",
|
||||
"a copy of this software and associated documentation files (the\"",
|
||||
"Software\"), to deal in the Software without restriction, including",
|
||||
"without limitation the rights to use, copy, modify, merge, publish,",
|
||||
"distribute, sublicense, and/or sell copies of the Software, and to",
|
||||
"permit persons to whom the Software is furnished to do so, subject to",
|
||||
"the following conditions:",
|
||||
"",
|
||||
"The above copyright notice and this permission notice shall be",
|
||||
"included in all copies or substantial portions of the Software.",
|
||||
"",
|
||||
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,",
|
||||
"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF",
|
||||
"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND",
|
||||
"NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE",
|
||||
"LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION",
|
||||
"OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION",
|
||||
"WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
|
||||
],
|
||||
"license": "MIT",
|
||||
"version": "0.0.0"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
20
extensions/git-base/extension-browser.webpack.config.js
Normal file
20
extensions/git-base/extension-browser.webpack.config.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
//@ts-check
|
||||
|
||||
'use strict';
|
||||
|
||||
const withBrowserDefaults = require('../shared.webpack.config').browser;
|
||||
|
||||
module.exports = withBrowserDefaults({
|
||||
context: __dirname,
|
||||
entry: {
|
||||
extension: './src/extension.ts'
|
||||
},
|
||||
output: {
|
||||
filename: 'extension.js'
|
||||
}
|
||||
});
|
||||
20
extensions/git-base/extension.webpack.config.js
Normal file
20
extensions/git-base/extension.webpack.config.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
//@ts-check
|
||||
|
||||
'use strict';
|
||||
|
||||
const withDefaults = require('../shared.webpack.config');
|
||||
|
||||
module.exports = withDefaults({
|
||||
context: __dirname,
|
||||
entry: {
|
||||
extension: './src/extension.ts'
|
||||
},
|
||||
output: {
|
||||
filename: 'extension.js'
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"comments": {
|
||||
"lineComment": "#",
|
||||
"blockComment": [ "#", " " ]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"comments": {
|
||||
"lineComment": "#",
|
||||
"blockComment": [ "#", " " ]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"comments": {
|
||||
"lineComment": "#",
|
||||
}
|
||||
}
|
||||
112
extensions/git-base/package.json
Normal file
112
extensions/git-base/package.json
Normal file
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"name": "git-base",
|
||||
"displayName": "%displayName%",
|
||||
"description": "%description%",
|
||||
"version": "1.0.0",
|
||||
"publisher": "vscode",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"vscode": "0.10.x"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"main": "./out/extension.js",
|
||||
"browser": "./dist/browser/extension.js",
|
||||
"icon": "resources/icons/git.png",
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:git-base",
|
||||
"watch": "gulp watch-extension:git-base",
|
||||
"update-grammar": "node ./build/update-grammars.js"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": true,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "git-base.api.getRemoteSources",
|
||||
"title": "%command.api.getRemoteSources%",
|
||||
"category": "Git Base API"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "git-base.api.getRemoteSources",
|
||||
"when": "false"
|
||||
}
|
||||
]
|
||||
},
|
||||
"languages": [
|
||||
{
|
||||
"id": "git-commit",
|
||||
"aliases": [
|
||||
"Git Commit Message",
|
||||
"git-commit"
|
||||
],
|
||||
"filenames": [
|
||||
"COMMIT_EDITMSG",
|
||||
"MERGE_MSG"
|
||||
],
|
||||
"configuration": "./languages/git-commit.language-configuration.json"
|
||||
},
|
||||
{
|
||||
"id": "git-rebase",
|
||||
"aliases": [
|
||||
"Git Rebase Message",
|
||||
"git-rebase"
|
||||
],
|
||||
"filenames": [
|
||||
"git-rebase-todo"
|
||||
],
|
||||
"configuration": "./languages/git-rebase.language-configuration.json"
|
||||
},
|
||||
{
|
||||
"id": "ignore",
|
||||
"aliases": [
|
||||
"Ignore",
|
||||
"ignore"
|
||||
],
|
||||
"extensions": [
|
||||
".gitignore_global",
|
||||
".gitignore"
|
||||
],
|
||||
"configuration": "./languages/ignore.language-configuration.json"
|
||||
}
|
||||
],
|
||||
"grammars": [
|
||||
{
|
||||
"language": "git-commit",
|
||||
"scopeName": "text.git-commit",
|
||||
"path": "./syntaxes/git-commit.tmLanguage.json"
|
||||
},
|
||||
{
|
||||
"language": "git-rebase",
|
||||
"scopeName": "text.git-rebase",
|
||||
"path": "./syntaxes/git-rebase.tmLanguage.json"
|
||||
},
|
||||
{
|
||||
"language": "ignore",
|
||||
"scopeName": "source.ignore",
|
||||
"path": "./syntaxes/ignore.tmLanguage.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-nls": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "16.x"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/microsoft/vscode.git"
|
||||
}
|
||||
}
|
||||
5
extensions/git-base/package.nls.json
Normal file
5
extensions/git-base/package.nls.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"displayName": "Git Base",
|
||||
"description": "Git static contributions and pickers.",
|
||||
"command.api.getRemoteSources": "Get Remote Sources"
|
||||
}
|
||||
BIN
extensions/git-base/resources/icons/git.png
Normal file
BIN
extensions/git-base/resources/icons/git.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
37
extensions/git-base/src/api/api1.ts
Normal file
37
extensions/git-base/src/api/api1.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable, commands } from 'vscode';
|
||||
import { Model } from '../model';
|
||||
import { pickRemoteSource } from '../remoteSource';
|
||||
import { GitBaseExtensionImpl } from './extension';
|
||||
import { API, PickRemoteSourceOptions, PickRemoteSourceResult, RemoteSourceProvider } from './git-base';
|
||||
|
||||
export class ApiImpl implements API {
|
||||
|
||||
constructor(private _model: Model) { }
|
||||
|
||||
pickRemoteSource(options: PickRemoteSourceOptions): Promise<PickRemoteSourceResult | string | undefined> {
|
||||
return pickRemoteSource(this._model, options as any);
|
||||
}
|
||||
|
||||
registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable {
|
||||
return this._model.registerRemoteSourceProvider(provider);
|
||||
}
|
||||
}
|
||||
|
||||
export function registerAPICommands(extension: GitBaseExtensionImpl): Disposable {
|
||||
const disposables: Disposable[] = [];
|
||||
|
||||
disposables.push(commands.registerCommand('git-base.api.getRemoteSources', (opts?: PickRemoteSourceOptions) => {
|
||||
if (!extension.model) {
|
||||
return;
|
||||
}
|
||||
|
||||
return pickRemoteSource(extension.model, opts as any);
|
||||
}));
|
||||
|
||||
return Disposable.from(...disposables);
|
||||
}
|
||||
55
extensions/git-base/src/api/extension.ts
Normal file
55
extensions/git-base/src/api/extension.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Model } from '../model';
|
||||
import { GitBaseExtension, API } from './git-base';
|
||||
import { Event, EventEmitter } from 'vscode';
|
||||
import { ApiImpl } from './api1';
|
||||
|
||||
export class GitBaseExtensionImpl implements GitBaseExtension {
|
||||
|
||||
enabled: boolean = false;
|
||||
|
||||
private _onDidChangeEnablement = new EventEmitter<boolean>();
|
||||
readonly onDidChangeEnablement: Event<boolean> = this._onDidChangeEnablement.event;
|
||||
|
||||
private _model: Model | undefined = undefined;
|
||||
|
||||
set model(model: Model | undefined) {
|
||||
this._model = model;
|
||||
|
||||
const enabled = !!model;
|
||||
|
||||
if (this.enabled === enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.enabled = enabled;
|
||||
this._onDidChangeEnablement.fire(this.enabled);
|
||||
}
|
||||
|
||||
get model(): Model | undefined {
|
||||
return this._model;
|
||||
}
|
||||
|
||||
constructor(model?: Model) {
|
||||
if (model) {
|
||||
this.enabled = true;
|
||||
this._model = model;
|
||||
}
|
||||
}
|
||||
|
||||
getAPI(version: number): API {
|
||||
if (!this._model) {
|
||||
throw new Error('Git model not found');
|
||||
}
|
||||
|
||||
if (version !== 1) {
|
||||
throw new Error(`No API version ${version} found.`);
|
||||
}
|
||||
|
||||
return new ApiImpl(this._model);
|
||||
}
|
||||
}
|
||||
75
extensions/git-base/src/api/git-base.d.ts
vendored
Normal file
75
extensions/git-base/src/api/git-base.d.ts
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable, Event, ProviderResult, Uri } from 'vscode';
|
||||
export { ProviderResult } from 'vscode';
|
||||
|
||||
export interface API {
|
||||
registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable;
|
||||
pickRemoteSource(options: PickRemoteSourceOptions): Promise<string | PickRemoteSourceResult | undefined>;
|
||||
}
|
||||
|
||||
export interface GitBaseExtension {
|
||||
|
||||
readonly enabled: boolean;
|
||||
readonly onDidChangeEnablement: Event<boolean>;
|
||||
|
||||
/**
|
||||
* Returns a specific API version.
|
||||
*
|
||||
* Throws error if git-base extension is disabled. You can listed to the
|
||||
* [GitBaseExtension.onDidChangeEnablement](#GitBaseExtension.onDidChangeEnablement)
|
||||
* event to know when the extension becomes enabled/disabled.
|
||||
*
|
||||
* @param version Version number.
|
||||
* @returns API instance
|
||||
*/
|
||||
getAPI(version: 1): API;
|
||||
}
|
||||
|
||||
export interface PickRemoteSourceOptions {
|
||||
readonly providerLabel?: (provider: RemoteSourceProvider) => string;
|
||||
readonly urlLabel?: string | ((url: string) => string);
|
||||
readonly providerName?: string;
|
||||
readonly title?: string;
|
||||
readonly placeholder?: string;
|
||||
readonly branch?: boolean; // then result is PickRemoteSourceResult
|
||||
readonly showRecentSources?: boolean;
|
||||
}
|
||||
|
||||
export interface PickRemoteSourceResult {
|
||||
readonly url: string;
|
||||
readonly branch?: string;
|
||||
}
|
||||
|
||||
export interface RemoteSource {
|
||||
readonly name: string;
|
||||
readonly description?: string;
|
||||
readonly detail?: string;
|
||||
/**
|
||||
* Codicon name
|
||||
*/
|
||||
readonly icon?: string;
|
||||
readonly url: string | string[];
|
||||
}
|
||||
|
||||
export interface RecentRemoteSource extends RemoteSource {
|
||||
readonly timestamp: number;
|
||||
}
|
||||
|
||||
export interface RemoteSourceProvider {
|
||||
readonly name: string;
|
||||
/**
|
||||
* Codicon name
|
||||
*/
|
||||
readonly icon?: string;
|
||||
readonly label?: string;
|
||||
readonly placeholder?: string;
|
||||
readonly supportsQuery?: boolean;
|
||||
|
||||
getBranches?(url: string): ProviderResult<string[]>;
|
||||
getRecentRemoteSources?(query?: string): ProviderResult<RecentRemoteSource[]>;
|
||||
getRemoteSources(query?: string): ProviderResult<RemoteSource[]>;
|
||||
}
|
||||
69
extensions/git-base/src/decorators.ts
Normal file
69
extensions/git-base/src/decorators.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { done } from './util';
|
||||
|
||||
export function debounce(delay: number): Function {
|
||||
return decorate((fn, key) => {
|
||||
const timerKey = `$debounce$${key}`;
|
||||
|
||||
return function (this: any, ...args: any[]) {
|
||||
clearTimeout(this[timerKey]);
|
||||
this[timerKey] = setTimeout(() => fn.apply(this, args), delay);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export const throttle = decorate(_throttle);
|
||||
|
||||
function _throttle<T>(fn: Function, key: string): Function {
|
||||
const currentKey = `$throttle$current$${key}`;
|
||||
const nextKey = `$throttle$next$${key}`;
|
||||
|
||||
const trigger = function (this: any, ...args: any[]) {
|
||||
if (this[nextKey]) {
|
||||
return this[nextKey];
|
||||
}
|
||||
|
||||
if (this[currentKey]) {
|
||||
this[nextKey] = done(this[currentKey]).then(() => {
|
||||
this[nextKey] = undefined;
|
||||
return trigger.apply(this, args);
|
||||
});
|
||||
|
||||
return this[nextKey];
|
||||
}
|
||||
|
||||
this[currentKey] = fn.apply(this, args) as Promise<T>;
|
||||
|
||||
const clear = () => this[currentKey] = undefined;
|
||||
done(this[currentKey]).then(clear, clear);
|
||||
|
||||
return this[currentKey];
|
||||
};
|
||||
|
||||
return trigger;
|
||||
}
|
||||
|
||||
function decorate(decorator: (fn: Function, key: string) => Function): Function {
|
||||
return (_target: any, key: string, descriptor: any) => {
|
||||
let fnKey: string | null = null;
|
||||
let fn: Function | null = null;
|
||||
|
||||
if (typeof descriptor.value === 'function') {
|
||||
fnKey = 'value';
|
||||
fn = descriptor.value;
|
||||
} else if (typeof descriptor.get === 'function') {
|
||||
fnKey = 'get';
|
||||
fn = descriptor.get;
|
||||
}
|
||||
|
||||
if (!fn || !fnKey) {
|
||||
throw new Error('not supported');
|
||||
}
|
||||
|
||||
descriptor[fnKey] = decorator(fn, key);
|
||||
};
|
||||
}
|
||||
16
extensions/git-base/src/extension.ts
Normal file
16
extensions/git-base/src/extension.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ExtensionContext } from 'vscode';
|
||||
import { registerAPICommands } from './api/api1';
|
||||
import { GitBaseExtensionImpl } from './api/extension';
|
||||
import { Model } from './model';
|
||||
|
||||
export function activate(context: ExtensionContext): GitBaseExtensionImpl {
|
||||
const apiImpl = new GitBaseExtensionImpl(new Model());
|
||||
context.subscriptions.push(registerAPICommands(apiImpl));
|
||||
|
||||
return apiImpl;
|
||||
}
|
||||
34
extensions/git-base/src/model.ts
Normal file
34
extensions/git-base/src/model.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { EventEmitter, Disposable } from 'vscode';
|
||||
import { toDisposable } from './util';
|
||||
import { RemoteSourceProvider } from './api/git-base';
|
||||
import { IRemoteSourceProviderRegistry } from './remoteProvider';
|
||||
|
||||
export class Model implements IRemoteSourceProviderRegistry {
|
||||
|
||||
private remoteSourceProviders = new Set<RemoteSourceProvider>();
|
||||
|
||||
private _onDidAddRemoteSourceProvider = new EventEmitter<RemoteSourceProvider>();
|
||||
readonly onDidAddRemoteSourceProvider = this._onDidAddRemoteSourceProvider.event;
|
||||
|
||||
private _onDidRemoveRemoteSourceProvider = new EventEmitter<RemoteSourceProvider>();
|
||||
readonly onDidRemoveRemoteSourceProvider = this._onDidRemoveRemoteSourceProvider.event;
|
||||
|
||||
registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable {
|
||||
this.remoteSourceProviders.add(provider);
|
||||
this._onDidAddRemoteSourceProvider.fire(provider);
|
||||
|
||||
return toDisposable(() => {
|
||||
this.remoteSourceProviders.delete(provider);
|
||||
this._onDidRemoveRemoteSourceProvider.fire(provider);
|
||||
});
|
||||
}
|
||||
|
||||
getRemoteProviders(): RemoteSourceProvider[] {
|
||||
return [...this.remoteSourceProviders.values()];
|
||||
}
|
||||
}
|
||||
15
extensions/git-base/src/remoteProvider.ts
Normal file
15
extensions/git-base/src/remoteProvider.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable, Event } from 'vscode';
|
||||
import { RemoteSourceProvider } from './api/git-base';
|
||||
|
||||
export interface IRemoteSourceProviderRegistry {
|
||||
readonly onDidAddRemoteSourceProvider: Event<RemoteSourceProvider>;
|
||||
readonly onDidRemoveRemoteSourceProvider: Event<RemoteSourceProvider>;
|
||||
|
||||
getRemoteProviders(): RemoteSourceProvider[];
|
||||
registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable;
|
||||
}
|
||||
199
extensions/git-base/src/remoteSource.ts
Normal file
199
extensions/git-base/src/remoteSource.ts
Normal file
@@ -0,0 +1,199 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { QuickPickItem, window, QuickPick, QuickPickItemKind } from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { RemoteSourceProvider, RemoteSource, PickRemoteSourceOptions, PickRemoteSourceResult } from './api/git-base';
|
||||
import { Model } from './model';
|
||||
import { throttle, debounce } from './decorators';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
async function getQuickPickResult<T extends QuickPickItem>(quickpick: QuickPick<T>): Promise<T | undefined> {
|
||||
const result = await new Promise<T | undefined>(c => {
|
||||
quickpick.onDidAccept(() => c(quickpick.selectedItems[0]));
|
||||
quickpick.onDidHide(() => c(undefined));
|
||||
quickpick.show();
|
||||
});
|
||||
|
||||
quickpick.hide();
|
||||
return result;
|
||||
}
|
||||
|
||||
class RemoteSourceProviderQuickPick {
|
||||
|
||||
private quickpick: QuickPick<QuickPickItem & { remoteSource?: RemoteSource }> | undefined;
|
||||
|
||||
constructor(private provider: RemoteSourceProvider) { }
|
||||
|
||||
private ensureQuickPick() {
|
||||
if (!this.quickpick) {
|
||||
this.quickpick = window.createQuickPick();
|
||||
this.quickpick.ignoreFocusOut = true;
|
||||
if (this.provider.supportsQuery) {
|
||||
this.quickpick.placeholder = this.provider.placeholder ?? localize('type to search', "Repository name (type to search)");
|
||||
this.quickpick.onDidChangeValue(this.onDidChangeValue, this);
|
||||
} else {
|
||||
this.quickpick.placeholder = this.provider.placeholder ?? localize('type to filter', "Repository name");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@debounce(300)
|
||||
private onDidChangeValue(): void {
|
||||
this.query();
|
||||
}
|
||||
|
||||
@throttle
|
||||
private async query(): Promise<void> {
|
||||
try {
|
||||
const remoteSources = await this.provider.getRemoteSources(this.quickpick?.value) || [];
|
||||
|
||||
this.ensureQuickPick();
|
||||
this.quickpick!.show();
|
||||
|
||||
if (remoteSources.length === 0) {
|
||||
this.quickpick!.items = [{
|
||||
label: localize('none found', "No remote repositories found."),
|
||||
alwaysShow: true
|
||||
}];
|
||||
} else {
|
||||
this.quickpick!.items = remoteSources.map(remoteSource => ({
|
||||
label: remoteSource.icon ? `$(${remoteSource.icon}) ${remoteSource.name}` : remoteSource.name,
|
||||
description: remoteSource.description || (typeof remoteSource.url === 'string' ? remoteSource.url : remoteSource.url[0]),
|
||||
detail: remoteSource.detail,
|
||||
remoteSource,
|
||||
alwaysShow: true
|
||||
}));
|
||||
}
|
||||
} catch (err) {
|
||||
this.quickpick!.items = [{ label: localize('error', "$(error) Error: {0}", err.message), alwaysShow: true }];
|
||||
console.error(err);
|
||||
} finally {
|
||||
this.quickpick!.busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
async pick(): Promise<RemoteSource | undefined> {
|
||||
await this.query();
|
||||
const result = await getQuickPickResult(this.quickpick!);
|
||||
return result?.remoteSource;
|
||||
}
|
||||
}
|
||||
|
||||
export async function pickRemoteSource(model: Model, options: PickRemoteSourceOptions & { branch?: false | undefined }): Promise<string | undefined>;
|
||||
export async function pickRemoteSource(model: Model, options: PickRemoteSourceOptions & { branch: true }): Promise<PickRemoteSourceResult | undefined>;
|
||||
export async function pickRemoteSource(model: Model, options: PickRemoteSourceOptions = {}): Promise<string | PickRemoteSourceResult | undefined> {
|
||||
const quickpick = window.createQuickPick<(QuickPickItem & { provider?: RemoteSourceProvider; url?: string })>();
|
||||
quickpick.ignoreFocusOut = true;
|
||||
quickpick.title = options.title;
|
||||
|
||||
if (options.providerName) {
|
||||
const provider = model.getRemoteProviders()
|
||||
.filter(provider => provider.name === options.providerName)[0];
|
||||
|
||||
if (provider) {
|
||||
return await pickProviderSource(provider, options);
|
||||
}
|
||||
}
|
||||
|
||||
const remoteProviders = model.getRemoteProviders()
|
||||
.map(provider => ({ label: (provider.icon ? `$(${provider.icon}) ` : '') + (options.providerLabel ? options.providerLabel(provider) : provider.name), alwaysShow: true, provider }));
|
||||
|
||||
const recentSources: (QuickPickItem & { url?: string; timestamp: number })[] = [];
|
||||
if (options.showRecentSources) {
|
||||
for (const { provider } of remoteProviders) {
|
||||
const sources = (await provider.getRecentRemoteSources?.() ?? []).map((item) => {
|
||||
return {
|
||||
...item,
|
||||
label: (item.icon ? `$(${item.icon}) ` : '') + item.name,
|
||||
url: typeof item.url === 'string' ? item.url : item.url[0],
|
||||
};
|
||||
});
|
||||
recentSources.push(...sources);
|
||||
}
|
||||
}
|
||||
|
||||
const items = [
|
||||
{ kind: QuickPickItemKind.Separator, label: localize('remote sources', 'remote sources') },
|
||||
...remoteProviders,
|
||||
{ kind: QuickPickItemKind.Separator, label: localize('recently opened', 'recently opened') },
|
||||
...recentSources.sort((a, b) => b.timestamp - a.timestamp)
|
||||
];
|
||||
|
||||
quickpick.placeholder = options.placeholder ?? (remoteProviders.length === 0
|
||||
? localize('provide url', "Provide repository URL")
|
||||
: localize('provide url or pick', "Provide repository URL or pick a repository source."));
|
||||
|
||||
const updatePicks = (value?: string) => {
|
||||
if (value) {
|
||||
const label = (typeof options.urlLabel === 'string' ? options.urlLabel : options.urlLabel?.(value)) ?? localize('url', "URL");
|
||||
quickpick.items = [{
|
||||
label: label,
|
||||
description: value,
|
||||
alwaysShow: true,
|
||||
url: value
|
||||
},
|
||||
...items
|
||||
];
|
||||
} else {
|
||||
quickpick.items = items;
|
||||
}
|
||||
};
|
||||
|
||||
quickpick.onDidChangeValue(updatePicks);
|
||||
updatePicks();
|
||||
|
||||
const result = await getQuickPickResult(quickpick);
|
||||
|
||||
if (result) {
|
||||
if (result.url) {
|
||||
return result.url;
|
||||
} else if (result.provider) {
|
||||
return await pickProviderSource(result.provider, options);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async function pickProviderSource(provider: RemoteSourceProvider, options: PickRemoteSourceOptions = {}): Promise<string | PickRemoteSourceResult | undefined> {
|
||||
const quickpick = new RemoteSourceProviderQuickPick(provider);
|
||||
const remote = await quickpick.pick();
|
||||
|
||||
let url: string | undefined;
|
||||
|
||||
if (remote) {
|
||||
if (typeof remote.url === 'string') {
|
||||
url = remote.url;
|
||||
} else if (remote.url.length > 0) {
|
||||
url = await window.showQuickPick(remote.url, { ignoreFocusOut: true, placeHolder: localize('pick url', "Choose a URL to clone from.") });
|
||||
}
|
||||
}
|
||||
|
||||
if (!url || !options.branch) {
|
||||
return url;
|
||||
}
|
||||
|
||||
if (!provider.getBranches) {
|
||||
return { url };
|
||||
}
|
||||
|
||||
const branches = await provider.getBranches(url);
|
||||
|
||||
if (!branches) {
|
||||
return { url };
|
||||
}
|
||||
|
||||
const branch = await window.showQuickPick(branches, {
|
||||
placeHolder: localize('branch name', "Branch name")
|
||||
});
|
||||
|
||||
if (!branch) {
|
||||
return { url };
|
||||
}
|
||||
|
||||
return { url, branch };
|
||||
}
|
||||
69
extensions/git-base/src/util.ts
Normal file
69
extensions/git-base/src/util.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export interface IDisposable {
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export function toDisposable(dispose: () => void): IDisposable {
|
||||
return { dispose };
|
||||
}
|
||||
|
||||
export function done<T>(promise: Promise<T>): Promise<void> {
|
||||
return promise.then<void>(() => undefined);
|
||||
}
|
||||
|
||||
export namespace Versions {
|
||||
declare type VersionComparisonResult = -1 | 0 | 1;
|
||||
|
||||
export interface Version {
|
||||
major: number;
|
||||
minor: number;
|
||||
patch: number;
|
||||
pre?: string;
|
||||
}
|
||||
|
||||
export function compare(v1: string | Version, v2: string | Version): VersionComparisonResult {
|
||||
if (typeof v1 === 'string') {
|
||||
v1 = fromString(v1);
|
||||
}
|
||||
if (typeof v2 === 'string') {
|
||||
v2 = fromString(v2);
|
||||
}
|
||||
|
||||
if (v1.major > v2.major) { return 1; }
|
||||
if (v1.major < v2.major) { return -1; }
|
||||
|
||||
if (v1.minor > v2.minor) { return 1; }
|
||||
if (v1.minor < v2.minor) { return -1; }
|
||||
|
||||
if (v1.patch > v2.patch) { return 1; }
|
||||
if (v1.patch < v2.patch) { return -1; }
|
||||
|
||||
if (v1.pre === undefined && v2.pre !== undefined) { return 1; }
|
||||
if (v1.pre !== undefined && v2.pre === undefined) { return -1; }
|
||||
|
||||
if (v1.pre !== undefined && v2.pre !== undefined) {
|
||||
return v1.pre.localeCompare(v2.pre) as VersionComparisonResult;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
export function from(major: string | number, minor: string | number, patch?: string | number, pre?: string): Version {
|
||||
return {
|
||||
major: typeof major === 'string' ? parseInt(major, 10) : major,
|
||||
minor: typeof minor === 'string' ? parseInt(minor, 10) : minor,
|
||||
patch: patch === undefined || patch === null ? 0 : typeof patch === 'string' ? parseInt(patch, 10) : patch,
|
||||
pre: pre,
|
||||
};
|
||||
}
|
||||
|
||||
export function fromString(version: string): Version {
|
||||
const [ver, pre] = version.split('-');
|
||||
const [major, minor, patch] = ver.split('.');
|
||||
return from(major, minor, patch, pre);
|
||||
}
|
||||
}
|
||||
141
extensions/git-base/syntaxes/git-commit.tmLanguage.json
Normal file
141
extensions/git-base/syntaxes/git-commit.tmLanguage.json
Normal file
@@ -0,0 +1,141 @@
|
||||
{
|
||||
"information_for_contributors": [
|
||||
"This file has been converted from https://github.com/textmate/git.tmbundle/blob/master/Syntaxes/Git%20Commit%20Message.tmLanguage",
|
||||
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
|
||||
"Once accepted there, we are happy to receive an update request."
|
||||
],
|
||||
"version": "https://github.com/textmate/git.tmbundle/commit/93897a78c6e52bef13dadc0d4091d203c5facb40",
|
||||
"name": "Git Commit Message",
|
||||
"scopeName": "text.git-commit",
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "\\A(?!# Please enter the commit message)",
|
||||
"end": "^(?=# Please enter the commit message)",
|
||||
"name": "meta.scope.message.git-commit",
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "\\A(?=#)",
|
||||
"end": "^(?!#)",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#comment"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "^(?!# Please enter the commit message)",
|
||||
"end": "^(?=# Please enter the commit message)",
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "\\G",
|
||||
"end": "^(?!\\G)",
|
||||
"name": "meta.scope.subject.git-commit",
|
||||
"patterns": [
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "keyword.other.$2.git-commit"
|
||||
}
|
||||
},
|
||||
"match": "\\G((fixup|squash)!)\\s*"
|
||||
},
|
||||
{
|
||||
"match": ".{73,}$",
|
||||
"name": "invalid.illegal.line-too-long.git-commit"
|
||||
},
|
||||
{
|
||||
"match": ".{51,}$",
|
||||
"name": "invalid.deprecated.line-too-long.git-commit"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "^(?!# Please enter the commit message)",
|
||||
"end": "^(?=# Please enter the commit message)",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#comment"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "^(?=# Please enter the commit message)",
|
||||
"end": "\\z",
|
||||
"name": "meta.scope.metadata.git-commit",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#metadata"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"comment": {
|
||||
"begin": "^(#)",
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.comment.git-commit"
|
||||
}
|
||||
},
|
||||
"end": "\\n",
|
||||
"name": "comment.line.number-sign.git-commit"
|
||||
},
|
||||
"metadata": {
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "(?=^# Changes to be committed:)",
|
||||
"end": "(?!\\G)((?=^# \\w)|(?!^#))",
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "(^[ \\t]+)?(?=#)",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "punctuation.whitespace.comment.leading.git-commit"
|
||||
}
|
||||
},
|
||||
"contentName": "comment.line.number-sign.git-commit",
|
||||
"end": "(?!\\G)^",
|
||||
"patterns": [
|
||||
{
|
||||
"match": "\\G#",
|
||||
"name": "punctuation.definition.comment.git-commit"
|
||||
},
|
||||
{
|
||||
"match": "((modified|renamed):.*)$\\n?",
|
||||
"name": "markup.changed.git-commit"
|
||||
},
|
||||
{
|
||||
"match": "(new file:.*)$\\n?",
|
||||
"name": "markup.inserted.git-commit"
|
||||
},
|
||||
{
|
||||
"match": "(deleted:.*)$\\n?",
|
||||
"name": "markup.deleted.git-commit"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"include": "#comment"
|
||||
},
|
||||
{
|
||||
"begin": "(?=diff\\ \\-\\-git)",
|
||||
"comment": "diff presented at the end of the commit message when using commit -v.",
|
||||
"contentName": "source.diff",
|
||||
"end": "\\z",
|
||||
"name": "meta.embedded.diff.git-commit",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "source.diff"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
61
extensions/git-base/syntaxes/git-rebase.tmLanguage.json
Normal file
61
extensions/git-base/syntaxes/git-rebase.tmLanguage.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"information_for_contributors": [
|
||||
"This file has been converted from https://github.com/textmate/git.tmbundle/blob/master/Syntaxes/Git%20Rebase%20Message.tmLanguage",
|
||||
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
|
||||
"Once accepted there, we are happy to receive an update request."
|
||||
],
|
||||
"version": "https://github.com/textmate/git.tmbundle/commit/5870cf3f8abad3a6637bdf69250b5d2ded427dc4",
|
||||
"name": "Git Rebase Message",
|
||||
"scopeName": "text.git-rebase",
|
||||
"patterns": [
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.comment.git-rebase"
|
||||
}
|
||||
},
|
||||
"match": "^\\s*(#).*$\\n?",
|
||||
"name": "comment.line.number-sign.git-rebase"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "support.function.git-rebase"
|
||||
},
|
||||
"2": {
|
||||
"name": "constant.sha.git-rebase"
|
||||
},
|
||||
"3": {
|
||||
"name": "meta.commit-message.git-rebase"
|
||||
}
|
||||
},
|
||||
"match": "^\\s*(pick|p|reword|r|edit|e|squash|s|fixup|f|drop|d)\\s+([0-9a-f]+)\\s+(.*)$",
|
||||
"name": "meta.commit-command.git-rebase"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "support.function.git-rebase"
|
||||
},
|
||||
"2": {
|
||||
"patterns": [
|
||||
{
|
||||
"include": "source.shell"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"match": "^\\s*(exec|x)\\s+(.*)$",
|
||||
"name": "meta.commit-command.git-rebase"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "support.function.git-rebase"
|
||||
}
|
||||
},
|
||||
"match": "^\\s*(break|b)\\s*$",
|
||||
"name": "meta.commit-command.git-rebase"
|
||||
}
|
||||
]
|
||||
}
|
||||
10
extensions/git-base/syntaxes/ignore.tmLanguage.json
Normal file
10
extensions/git-base/syntaxes/ignore.tmLanguage.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "Ignore",
|
||||
"scopeName": "source.ignore",
|
||||
"patterns": [
|
||||
{
|
||||
"match": "^#.*",
|
||||
"name": "comment.line.number-sign.ignore"
|
||||
}
|
||||
]
|
||||
}
|
||||
14
extensions/git-base/tsconfig.json
Normal file
14
extensions/git-base/tsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out",
|
||||
"experimentalDecorators": true,
|
||||
"typeRoots": [
|
||||
"./node_modules/@types"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../src/vscode-dts/vscode.d.ts"
|
||||
]
|
||||
}
|
||||
13
extensions/git-base/yarn.lock
Normal file
13
extensions/git-base/yarn.lock
Normal file
@@ -0,0 +1,13 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@16.x":
|
||||
version "16.11.21"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.21.tgz#474d7589a30afcf5291f59bd49cca9ad171ffde4"
|
||||
integrity sha512-Pf8M1XD9i1ksZEcCP8vuSNwooJ/bZapNmIzpmsMaL+jMI+8mEYU3PKvs+xDNuQcJWF/x24WzY4qxLtB0zNow9A==
|
||||
|
||||
vscode-nls@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840"
|
||||
integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA==
|
||||
Reference in New Issue
Block a user