SQL Operations Studio Public Preview 1 (0.23) release source code

This commit is contained in:
Karl Burtram
2017-11-09 14:30:27 -08:00
parent b88ecb8d93
commit 3cdac41339
8829 changed files with 759707 additions and 286 deletions

View File

@@ -0,0 +1,343 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as nls from 'vs/nls';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { valid } from 'semver';
import { join } from 'path';
export interface IParsedVersion {
hasCaret: boolean;
hasGreaterEquals: boolean;
majorBase: number;
majorMustEqual: boolean;
minorBase: number;
minorMustEqual: boolean;
patchBase: number;
patchMustEqual: boolean;
preRelease: string;
}
export interface INormalizedVersion {
majorBase: number;
majorMustEqual: boolean;
minorBase: number;
minorMustEqual: boolean;
patchBase: number;
patchMustEqual: boolean;
isMinimum: boolean;
}
const VERSION_REGEXP = /^(\^|>=)?((\d+)|x)\.((\d+)|x)\.((\d+)|x)(\-.*)?$/;
export function isValidVersionStr(version: string): boolean {
version = version.trim();
return (version === '*' || VERSION_REGEXP.test(version));
}
export function parseVersion(version: string): IParsedVersion {
if (!isValidVersionStr(version)) {
return null;
}
version = version.trim();
if (version === '*') {
return {
hasCaret: false,
hasGreaterEquals: false,
majorBase: 0,
majorMustEqual: false,
minorBase: 0,
minorMustEqual: false,
patchBase: 0,
patchMustEqual: false,
preRelease: null
};
}
let m = version.match(VERSION_REGEXP);
return {
hasCaret: m[1] === '^',
hasGreaterEquals: m[1] === '>=',
majorBase: m[2] === 'x' ? 0 : parseInt(m[2], 10),
majorMustEqual: (m[2] === 'x' ? false : true),
minorBase: m[4] === 'x' ? 0 : parseInt(m[4], 10),
minorMustEqual: (m[4] === 'x' ? false : true),
patchBase: m[6] === 'x' ? 0 : parseInt(m[6], 10),
patchMustEqual: (m[6] === 'x' ? false : true),
preRelease: m[8] || null
};
}
export function normalizeVersion(version: IParsedVersion): INormalizedVersion {
if (!version) {
return null;
}
let majorBase = version.majorBase,
majorMustEqual = version.majorMustEqual,
minorBase = version.minorBase,
minorMustEqual = version.minorMustEqual,
patchBase = version.patchBase,
patchMustEqual = version.patchMustEqual;
if (version.hasCaret) {
if (majorBase === 0) {
patchMustEqual = false;
} else {
minorMustEqual = false;
patchMustEqual = false;
}
}
return {
majorBase: majorBase,
majorMustEqual: majorMustEqual,
minorBase: minorBase,
minorMustEqual: minorMustEqual,
patchBase: patchBase,
patchMustEqual: patchMustEqual,
isMinimum: version.hasGreaterEquals
};
}
export function isValidVersion(_version: string | INormalizedVersion, _desiredVersion: string | INormalizedVersion): boolean {
let version: INormalizedVersion;
if (typeof _version === 'string') {
version = normalizeVersion(parseVersion(_version));
} else {
version = _version;
}
let desiredVersion: INormalizedVersion;
if (typeof _desiredVersion === 'string') {
desiredVersion = normalizeVersion(parseVersion(_desiredVersion));
} else {
desiredVersion = _desiredVersion;
}
if (!version || !desiredVersion) {
return false;
}
let majorBase = version.majorBase;
let minorBase = version.minorBase;
let patchBase = version.patchBase;
let desiredMajorBase = desiredVersion.majorBase;
let desiredMinorBase = desiredVersion.minorBase;
let desiredPatchBase = desiredVersion.patchBase;
let majorMustEqual = desiredVersion.majorMustEqual;
let minorMustEqual = desiredVersion.minorMustEqual;
let patchMustEqual = desiredVersion.patchMustEqual;
if (desiredVersion.isMinimum) {
if (majorBase > desiredMajorBase) {
return true;
}
if (majorBase < desiredMajorBase) {
return false;
}
if (minorBase > desiredMinorBase) {
return true;
}
if (minorBase < desiredMinorBase) {
return false;
}
return patchBase >= desiredPatchBase;
}
// Anything < 1.0.0 is compatible with >= 1.0.0, except exact matches
if (majorBase === 1 && desiredMajorBase === 0 && (!majorMustEqual || !minorMustEqual || !patchMustEqual)) {
desiredMajorBase = 1;
desiredMinorBase = 0;
desiredPatchBase = 0;
majorMustEqual = true;
minorMustEqual = false;
patchMustEqual = false;
}
if (majorBase < desiredMajorBase) {
// smaller major version
return false;
}
if (majorBase > desiredMajorBase) {
// higher major version
return (!majorMustEqual);
}
// at this point, majorBase are equal
if (minorBase < desiredMinorBase) {
// smaller minor version
return false;
}
if (minorBase > desiredMinorBase) {
// higher minor version
return (!minorMustEqual);
}
// at this point, minorBase are equal
if (patchBase < desiredPatchBase) {
// smaller patch version
return false;
}
if (patchBase > desiredPatchBase) {
// higher patch version
return (!patchMustEqual);
}
// at this point, patchBase are equal
return true;
}
export interface IReducedExtensionDescription {
isBuiltin: boolean;
engines: {
vscode: string;
};
main?: string;
}
export function isValidExtensionVersion(version: string, extensionDesc: IReducedExtensionDescription, notices: string[]): boolean {
if (extensionDesc.isBuiltin || typeof extensionDesc.main === 'undefined') {
// No version check for builtin or declarative extensions
return true;
}
return isVersionValid(version, extensionDesc.engines.vscode, notices);
}
export function isVersionValid(currentVersion: string, requestedVersion: string, notices: string[] = []): boolean {
let desiredVersion = normalizeVersion(parseVersion(requestedVersion));
if (!desiredVersion) {
notices.push(nls.localize('versionSyntax', "Could not parse `engines.vscode` value {0}. Please use, for example: ^0.10.0, ^1.2.3, ^0.11.0, ^0.10.x, etc.", requestedVersion));
return false;
}
// enforce that a breaking API version is specified.
// for 0.X.Y, that means up to 0.X must be specified
// otherwise for Z.X.Y, that means Z must be specified
if (desiredVersion.majorBase === 0) {
// force that major and minor must be specific
if (!desiredVersion.majorMustEqual || !desiredVersion.minorMustEqual) {
notices.push(nls.localize('versionSpecificity1', "Version specified in `engines.vscode` ({0}) is not specific enough. For vscode versions before 1.0.0, please define at a minimum the major and minor desired version. E.g. ^0.10.0, 0.10.x, 0.11.0, etc.", requestedVersion));
return false;
}
} else {
// force that major must be specific
if (!desiredVersion.majorMustEqual) {
notices.push(nls.localize('versionSpecificity2', "Version specified in `engines.vscode` ({0}) is not specific enough. For vscode versions after 1.0.0, please define at a minimum the major desired version. E.g. ^1.10.0, 1.10.x, 1.x.x, 2.x.x, etc.", requestedVersion));
return false;
}
}
if (!isValidVersion(currentVersion, desiredVersion)) {
notices.push(nls.localize('versionMismatch', "Extension is not compatible with Code {0}. Extension requires: {1}.", currentVersion, requestedVersion));
return false;
}
return true;
}
function _isStringArray(arr: string[]): boolean {
if (!Array.isArray(arr)) {
return false;
}
for (let i = 0, len = arr.length; i < len; i++) {
if (typeof arr[i] !== 'string') {
return false;
}
}
return true;
}
function baseIsValidExtensionDescription(extensionFolderPath: string, extensionDescription: IExtensionDescription, notices: string[]): boolean {
if (!extensionDescription) {
notices.push(nls.localize('extensionDescription.empty', "Got empty extension description"));
return false;
}
if (typeof extensionDescription.publisher !== 'string') {
notices.push(nls.localize('extensionDescription.publisher', "property `{0}` is mandatory and must be of type `string`", 'publisher'));
return false;
}
if (typeof extensionDescription.name !== 'string') {
notices.push(nls.localize('extensionDescription.name', "property `{0}` is mandatory and must be of type `string`", 'name'));
return false;
}
if (typeof extensionDescription.version !== 'string') {
notices.push(nls.localize('extensionDescription.version', "property `{0}` is mandatory and must be of type `string`", 'version'));
return false;
}
if (!extensionDescription.engines) {
notices.push(nls.localize('extensionDescription.engines', "property `{0}` is mandatory and must be of type `object`", 'engines'));
return false;
}
if (typeof extensionDescription.engines.vscode !== 'string') {
notices.push(nls.localize('extensionDescription.engines.vscode', "property `{0}` is mandatory and must be of type `string`", 'engines.vscode'));
return false;
}
if (typeof extensionDescription.extensionDependencies !== 'undefined') {
if (!_isStringArray(extensionDescription.extensionDependencies)) {
notices.push(nls.localize('extensionDescription.extensionDependencies', "property `{0}` can be omitted or must be of type `string[]`", 'extensionDependencies'));
return false;
}
}
if (typeof extensionDescription.activationEvents !== 'undefined') {
if (!_isStringArray(extensionDescription.activationEvents)) {
notices.push(nls.localize('extensionDescription.activationEvents1', "property `{0}` can be omitted or must be of type `string[]`", 'activationEvents'));
return false;
}
if (typeof extensionDescription.main === 'undefined') {
notices.push(nls.localize('extensionDescription.activationEvents2', "properties `{0}` and `{1}` must both be specified or must both be omitted", 'activationEvents', 'main'));
return false;
}
}
if (typeof extensionDescription.main !== 'undefined') {
if (typeof extensionDescription.main !== 'string') {
notices.push(nls.localize('extensionDescription.main1', "property `{0}` can be omitted or must be of type `string`", 'main'));
return false;
} else {
let normalizedAbsolutePath = join(extensionFolderPath, extensionDescription.main);
if (normalizedAbsolutePath.indexOf(extensionFolderPath)) {
notices.push(nls.localize('extensionDescription.main2', "Expected `main` ({0}) to be included inside extension's folder ({1}). This might make the extension non-portable.", normalizedAbsolutePath, extensionFolderPath));
// not a failure case
}
}
if (typeof extensionDescription.activationEvents === 'undefined') {
notices.push(nls.localize('extensionDescription.main3', "properties `{0}` and `{1}` must both be specified or must both be omitted", 'activationEvents', 'main'));
return false;
}
}
return true;
}
export function isValidExtensionDescription(version: string, extensionFolderPath: string, extensionDescription: IExtensionDescription, notices: string[]): boolean {
if (!baseIsValidExtensionDescription(extensionFolderPath, extensionDescription, notices)) {
return false;
}
if (!valid(extensionDescription.version)) {
notices.push(nls.localize('notSemver', "Extension version is not semver compatible."));
return false;
}
return isValidExtensionVersion(version, extensionDescription, notices);
}