Refactoring

* Added more tests
* Allowed also exact versions again
This commit is contained in:
litetex 2020-04-04 19:23:59 +02:00
parent 561f9e2075
commit a5cce9bf9f
2 changed files with 143 additions and 37 deletions

View File

@ -13,6 +13,92 @@ import * as installer from '../src/installer';
const IS_WINDOWS = process.platform === 'win32'; const IS_WINDOWS = process.platform === 'win32';
describe('version tests', () => {
it('Exact normal version', async() => {
let versInfo = new installer.DotNetVersionInfo('3.1.201');
expect(versInfo.isExactVersion()).toBe(true);
expect(versInfo.version()).toBe('3.1.201');
});
it('Exact preview version', async() => {
let versInfo = new installer.DotNetVersionInfo('3.1.201-preview1');
expect(versInfo.isExactVersion()).toBe(true);
expect(versInfo.version()).toBe('3.1.201-preview1');
});
it('Generic x version', async() => {
let versInfo = new installer.DotNetVersionInfo('3.1.x');
expect(versInfo.isExactVersion()).toBe(false);
expect(versInfo.version()).toBe('3.1');
});
it('Generic * version', async() => {
let versInfo = new installer.DotNetVersionInfo('1.1.*');
expect(versInfo.isExactVersion()).toBe(false);
expect(versInfo.version()).toBe('1.1');
});
it('Generic -no patch- version', async() => {
let versInfo = new installer.DotNetVersionInfo('2.0');
expect(versInfo.isExactVersion()).toBe(false);
expect(versInfo.version()).toBe('2.0');
});
it('Generic -no minor- version', async() => {
expect(() => {
new installer.DotNetVersionInfo('2');
}).toThrow();
});
it('empty version', async() => {
expect(() => {
new installer.DotNetVersionInfo('');
}).toThrow();
});
it('malformed no patch but dot version', async() => {
expect(() => {
new installer.DotNetVersionInfo('1.2.');
}).toThrow();
});
it('malformed generic minor version', async() => {
expect(() => {
new installer.DotNetVersionInfo('1.*.2');
}).toThrow();
});
it('malformed generic major version', async() => {
expect(() => {
new installer.DotNetVersionInfo('*.2.2');
}).toThrow();
});
it('malformed letter version', async() => {
expect(() => {
new installer.DotNetVersionInfo('a.b.c');
}).toThrow();
});
it('malformed letter preview version', async() => {
expect(() => {
new installer.DotNetVersionInfo('a.b.c-preview');
}).toThrow();
});
it('malformed letter -no minor- version', async() => {
expect(() => {
new installer.DotNetVersionInfo('a.b');
}).toThrow();
});
})
describe('installer tests', () => { describe('installer tests', () => {
beforeAll(async () => { beforeAll(async () => {
await io.rmRF(toolDir); await io.rmRF(toolDir);
@ -28,7 +114,6 @@ describe('installer tests', () => {
} }
}, 100000); }, 100000);
/*
it('Check if get version works', async () => { it('Check if get version works', async () => {
@ -48,7 +133,7 @@ describe('installer tests', () => {
expect(true).toBe(true); expect(true).toBe(true);
}, 400000);*/ }, 400000);
it('Acquires version of dotnet if no matching version is installed', async () => { it('Acquires version of dotnet if no matching version is installed', async () => {
await getDotnet('2.2.205'); await getDotnet('2.2.205');

View File

@ -10,6 +10,7 @@ import * as os from 'os';
import * as path from 'path'; import * as path from 'path';
import * as semver from 'semver'; import * as semver from 'semver';
import { stringWriter } from 'xmlbuilder'; import { stringWriter } from 'xmlbuilder';
import { timingSafeEqual } from 'crypto';
const IS_WINDOWS = process.platform === 'win32'; const IS_WINDOWS = process.platform === 'win32';
@ -28,16 +29,34 @@ if (!tempDirectory) {
tempDirectory = path.join(baseLocation, 'actions', 'temp'); tempDirectory = path.join(baseLocation, 'actions', 'temp');
} }
class DotNetVersionInfo { export class DotNetVersionInfo {
major: number;
minor: number; private fullversion : string;
patch?: number; private isExactVersionSet: boolean = false;
private major: number;
private minor: number;
private patch?: number;
constructor(version: string) { constructor(version: string) {
//todo: add support for previews!
let regexResult = version.match(/^(\d+\.)(\d+\.)(\*|x|\d+)$/); // Check for exact match
if(semver.valid(semver.clean(version) || '') != null) {
this.fullversion = semver.clean(version) as string;
this.isExactVersionSet = true;
this.major = semver.major(this.fullversion);
this.minor = semver.minor(this.fullversion);
this.patch = semver.patch(this.fullversion);
return;
}
//Note: No support for previews when using generic
let regexResult = version.match(/^(\d+\.)(\d+)?(\.\*|\.x|)$/);
if(regexResult == null) { if(regexResult == null) {
throw 'Invalid version. Supported formats: 1.2.3, 1.2, 1.2.x, 1.2.*'; throw 'Invalid version format! Supported: 1.2.3, 1.2, 1.2.x, 1.2.*';
} }
let parts : string[] = (regexResult as RegExpMatchArray).slice(1); let parts : string[] = (regexResult as RegExpMatchArray).slice(1);
@ -45,25 +64,18 @@ class DotNetVersionInfo {
this.major = +(parts[0].replace('.','')); this.major = +(parts[0].replace('.',''));
this.minor = +(parts[1].replace('.','')); this.minor = +(parts[1].replace('.',''));
if(parts.length > 2) { this.fullversion = this.major + '.' + this.minor;
// just set if it is a number
if(!isNaN(Number(parts[2]))) {
this.patch = +parts[2];
}
}
} }
public isGeneric() : boolean { /**
return this.patch ? true : false; * If true exacatly one version should be resolved
*/
public isExactVersion() : boolean {
return this.isExactVersionSet;
} }
public toString() : string { public version() : string {
let version = this.major + "." + this.minor; return this.fullversion;
if(this.patch)
version += "." + this.patch;
return version;
} }
} }
@ -102,12 +114,12 @@ export class DotnetCoreInstaller {
} }
// If version is not generic -> look up cache // If version is not generic -> look up cache
if(!this.versionInfo.isGeneric()) if(this.versionInfo.isExactVersion())
toolPath = this.getLocalTool(this.versionInfo.toString()); toolPath = this.getLocalTool(this.versionInfo.version());
if (!toolPath) { if (!toolPath) {
// download, extract, cache // download, extract, cache
console.log('Getting a download url', this.versionInfo.toString()); console.log('Getting a download url', this.versionInfo.version());
let resolvedVersionInfo = await this.resolveInfos(osSuffixes, this.versionInfo); let resolvedVersionInfo = await this.resolveInfos(osSuffixes, this.versionInfo);
//Check if cache exists for resolved version //Check if cache exists for resolved version
@ -246,7 +258,7 @@ export class DotnetCoreInstaller {
// OsSuffixes - The suffix which is a part of the file name ex- linux-x64, windows-x86 // OsSuffixes - The suffix which is a part of the file name ex- linux-x64, windows-x86
// Type - SDK / Runtime // Type - SDK / Runtime
// Version - Version of the SDK/Runtime // Version - Version of the SDK/Runtime
private async resolveInfos( async resolveInfos(
osSuffixes: string[], osSuffixes: string[],
versionInfo: DotNetVersionInfo versionInfo: DotNetVersionInfo
): Promise<ResolvedVersionInfo> { ): Promise<ResolvedVersionInfo> {
@ -255,9 +267,10 @@ export class DotnetCoreInstaller {
allowRetries: true, allowRetries: true,
maxRetries: 3 maxRetries: 3
}); });
const releasesJsonUrl: string = await this.getReleasesJsonUrl( const releasesJsonUrl: string = await this.getReleasesJsonUrl(
httpClient, httpClient,
[String(versionInfo.major), String(versionInfo.minor)] versionInfo.version().split('.')
); );
const releasesResponse = await httpClient.getJson<any>(releasesJsonUrl); const releasesResponse = await httpClient.getJson<any>(releasesJsonUrl);
@ -265,11 +278,19 @@ export class DotnetCoreInstaller {
let releasesInfo: any[] = releasesResult['releases']; let releasesInfo: any[] = releasesResult['releases'];
releasesInfo = releasesInfo.filter((releaseInfo: any) => { releasesInfo = releasesInfo.filter((releaseInfo: any) => {
return ( return (
semver.satisfies(releaseInfo['sdk']['version'], versionInfo.toString()) || semver.satisfies(releaseInfo['sdk']['version'], versionInfo.version()) ||
semver.satisfies(releaseInfo['sdk']['version-display'], versionInfo.toString()) semver.satisfies(releaseInfo['sdk']['version-display'], versionInfo.version())
); );
}); });
// Exclude versions that are newer than the latest if using not exact
if(!versionInfo.isExactVersion()) {
let latestSdk : string = releasesResponse['latest-sdk'];
releasesInfo = releasesInfo.filter((releaseInfo: any) => semver.lte(releaseInfo['sdk']['version'], latestSdk));
}
// Sort for latest version // Sort for latest version
releasesInfo = releasesInfo.sort((a,b) => semver.rcompare(a['sdk']['version'],b['sdk']['version'])); releasesInfo = releasesInfo.sort((a,b) => semver.rcompare(a['sdk']['version'],b['sdk']['version']));
@ -299,21 +320,21 @@ export class DotnetCoreInstaller {
} }
} else { } else {
console.log( console.log(
`Could not fetch download information for version ${versionInfo.toString()}` `Could not fetch download information for version ${versionInfo.version()}`
); );
if(!versionInfo.isGeneric()) { if(versionInfo.isExactVersion()) {
console.log('Using fallback'); console.log('Using fallback');
downloadUrls = await this.getFallbackDownloadUrls(versionInfo.toString()); downloadUrls = await this.getFallbackDownloadUrls(versionInfo.version());
downloadedVersion = versionInfo.toString(); downloadedVersion = versionInfo.version();
} else { } else {
console.log('Unable to use fallback, version is generic!'); console.log('Unable to use fallback, version is generic!');
} }
} }
if (downloadUrls.length == 0) { if (downloadUrls.length == 0) {
throw `Could not construct download URL. Please ensure that specified version ${versionInfo.toString()}/${downloadedVersion} is valid.`; throw `Could not construct download URL. Please ensure that specified version ${versionInfo.version()}/${downloadedVersion} is valid.`;
} }
core.debug(`Got download urls ${downloadUrls}`); core.debug(`Got download urls ${downloadUrls}`);