mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Add support for 4 part version numbers (#8925)
* first crack at fix * after test complete * pr feedback + tests * fix whitespace * PR fedback
This commit is contained in:
@@ -0,0 +1,62 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
import { SemVer } from 'semver';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function fourPart2SemVer(version: string): string {
|
||||||
|
if (version.includes('-')) {
|
||||||
|
//return unchanged if version contains a pre-release suffix
|
||||||
|
return version;
|
||||||
|
} else {
|
||||||
|
let parts: string[] = version.split('.');
|
||||||
|
if (parts.length > 3) {
|
||||||
|
version = `${parts[0]}.${parts[1]}.${parts[2]}+${parts.slice(3).join('.')}`;
|
||||||
|
}
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This Proxy for SemVer behaves the same way as the SamVer except the build number of the SemVer specification at: https://semver.org/ is prefixed by a '.' as well instead of a '+'. So while the BNF for valid SemVer is:
|
||||||
|
<valid semver> ::= <version core>
|
||||||
|
| <version core> "-" <pre-release>
|
||||||
|
| <version core> "+" <build>
|
||||||
|
| <version core> "-" <pre-release> "+" <build>
|
||||||
|
<version core> ::= <major> "." <minor> "." <patch>
|
||||||
|
|
||||||
|
SemVerProxy support the following BNF:
|
||||||
|
<valid semver> ::= <version core>
|
||||||
|
| <version core> "-" <pre-release>
|
||||||
|
| <version core> "." <build>
|
||||||
|
| <version core> "-" <pre-release> "+" <build>
|
||||||
|
<version core> ::= <major> "." <minor> "." <patch>
|
||||||
|
*/
|
||||||
|
export class SemVerProxy extends SemVer {
|
||||||
|
private _version: string;
|
||||||
|
|
||||||
|
constructor(version: string | SemVerProxy, loose?: boolean) {
|
||||||
|
let ver: string;
|
||||||
|
|
||||||
|
if (version instanceof SemVer) {
|
||||||
|
ver = version.version;
|
||||||
|
if (!ver) {
|
||||||
|
throw new Error('Invalid version');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ver = fourPart2SemVer(version);
|
||||||
|
}
|
||||||
|
super(ver, loose);
|
||||||
|
if (ver.includes('-')) {
|
||||||
|
this._version = ver;
|
||||||
|
} else {
|
||||||
|
this._version = ver.replace('+', '.'); // change back any '+' character used to delimit the build portion of the version with a '.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get version(): string {
|
||||||
|
return this._version;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import { AzdataInstallLocationKey, DeploymentConfigurationKey } from '../../cons
|
|||||||
import { Command, OsDistribution, ToolType } from '../../interfaces';
|
import { Command, OsDistribution, ToolType } from '../../interfaces';
|
||||||
import { IPlatformService } from '../platformService';
|
import { IPlatformService } from '../platformService';
|
||||||
import { dependencyType, ToolBase } from './toolBase';
|
import { dependencyType, ToolBase } from './toolBase';
|
||||||
|
import { SemVerProxy } from './SemVerProxy';
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
export const AzdataToolName = 'azdata';
|
export const AzdataToolName = 'azdata';
|
||||||
@@ -58,7 +59,7 @@ export class AzdataTool extends ToolBase {
|
|||||||
protected getVersionFromOutput(output: string): SemVer | undefined {
|
protected getVersionFromOutput(output: string): SemVer | undefined {
|
||||||
let version: SemVer | undefined = undefined;
|
let version: SemVer | undefined = undefined;
|
||||||
if (output && output.split(EOL).length > 0) {
|
if (output && output.split(EOL).length > 0) {
|
||||||
version = new SemVer(output.split(EOL)[0].replace(/ /g, ''));
|
version = new SemVerProxy(output.split(EOL)[0].replace(/ /g, ''));
|
||||||
}
|
}
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|||||||
95
extensions/resource-deployment/src/test/SemVerProxy.test.ts
Normal file
95
extensions/resource-deployment/src/test/SemVerProxy.test.ts
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import 'mocha';
|
||||||
|
import assert = require('assert');
|
||||||
|
import { SemVerProxy } from '../services/tools/SemVerProxy';
|
||||||
|
|
||||||
|
interface Expected {
|
||||||
|
[index: string]: string | number | undefined | Error
|
||||||
|
major?: number;
|
||||||
|
minor?: number;
|
||||||
|
patch?: number;
|
||||||
|
build?: string;
|
||||||
|
raw?: string;
|
||||||
|
prerelease?: string;
|
||||||
|
version?: string | Error
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TestDefinition {
|
||||||
|
testName: string;
|
||||||
|
inputVersion: string;
|
||||||
|
expected: Expected;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SymVerProxyTest extends SemVerProxy {
|
||||||
|
[index: string]: any;
|
||||||
|
constructor(version: string | SemVerProxy, loose?: boolean) {
|
||||||
|
super(version, loose);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testDefinitions: TestDefinition[] = [
|
||||||
|
{
|
||||||
|
testName: 'SemVerProxyTest: canonical 3 part version - Pre-existing common SymVers work as before', inputVersion: '1.2.3', expected: {
|
||||||
|
major: 1,
|
||||||
|
minor: 2,
|
||||||
|
patch: 3,
|
||||||
|
raw: '1.2.3',
|
||||||
|
version: '1.2.3'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: 'SemVerProxyTest: canonical 4 part version', inputVersion: '1.2.3.4', expected: {
|
||||||
|
major: 1,
|
||||||
|
minor: 2,
|
||||||
|
patch: 3,
|
||||||
|
build: '4',
|
||||||
|
raw: '1.2.3+4',
|
||||||
|
version: '1.2.3.4'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: 'SemVerProxyTest: canonical 8 part version', inputVersion: '1.2.3.4.5.6.7.8', expected: {
|
||||||
|
major: 1,
|
||||||
|
minor: 2,
|
||||||
|
patch: 3,
|
||||||
|
build: '4,5,6,7,8',
|
||||||
|
raw: '1.2.3+4.5.6.7.8',
|
||||||
|
version: '1.2.3.4.5.6.7.8'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: 'SemVerProxyTest: canonical pre-rel version', inputVersion: '1.2.3-rc1.22.33.44+55.66.77', expected: {
|
||||||
|
major: 1,
|
||||||
|
minor: 2,
|
||||||
|
patch: 3,
|
||||||
|
build: '55,66,77',
|
||||||
|
prerelease: 'rc1,22,33,44',
|
||||||
|
raw: '1.2.3-rc1.22.33.44+55.66.77',
|
||||||
|
version: '1.2.3-rc1.22.33.44+55.66.77'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
function validate(test: TestDefinition, semVerProxy: SymVerProxyTest) {
|
||||||
|
for (const key in test.expected) {
|
||||||
|
const expected = test.expected[key];
|
||||||
|
if (expected) {
|
||||||
|
assert.equal(semVerProxy[key].toString(), expected.toString(), `validation for property ${key} failed.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suite('SemVeryProxy Tests', function (): void {
|
||||||
|
testDefinitions.forEach((semVerTest: TestDefinition) => {
|
||||||
|
test(semVerTest.testName, () => {
|
||||||
|
const semVerProxy = new SymVerProxyTest(semVerTest.inputVersion);
|
||||||
|
validate(semVerTest, semVerProxy);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -102,7 +102,7 @@ export class ResourceTypePickerDialog extends DialogBase {
|
|||||||
};
|
};
|
||||||
const versionColumn: azdata.TableColumn = {
|
const versionColumn: azdata.TableColumn = {
|
||||||
value: localize('deploymentDialog.toolVersionColumnHeader', "Version"),
|
value: localize('deploymentDialog.toolVersionColumnHeader', "Version"),
|
||||||
width: 60
|
width: 75
|
||||||
};
|
};
|
||||||
const minVersionColumn: azdata.TableColumn = {
|
const minVersionColumn: azdata.TableColumn = {
|
||||||
value: localize('deploymentDialog.toolMinimumVersionColumnHeader', "Required Version"),
|
value: localize('deploymentDialog.toolMinimumVersionColumnHeader', "Required Version"),
|
||||||
@@ -110,7 +110,7 @@ export class ResourceTypePickerDialog extends DialogBase {
|
|||||||
};
|
};
|
||||||
const installedPathColumn: azdata.TableColumn = {
|
const installedPathColumn: azdata.TableColumn = {
|
||||||
value: localize('deploymentDialog.toolDiscoveredPathColumnHeader', "Discovered Path or Additional Information"),
|
value: localize('deploymentDialog.toolDiscoveredPathColumnHeader', "Discovered Path or Additional Information"),
|
||||||
width: 570
|
width: 580
|
||||||
};
|
};
|
||||||
this._toolsTable = view.modelBuilder.table().withProperties<azdata.TableComponentProperties>({
|
this._toolsTable = view.modelBuilder.table().withProperties<azdata.TableComponentProperties>({
|
||||||
data: [],
|
data: [],
|
||||||
|
|||||||
Reference in New Issue
Block a user