aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compiler-finder.ts (renamed from lib/compiler-finder.js)76
-rw-r--r--lib/properties.ts59
2 files changed, 103 insertions, 32 deletions
diff --git a/lib/compiler-finder.js b/lib/compiler-finder.ts
index 48f62d81d..332842441 100644
--- a/lib/compiler-finder.js
+++ b/lib/compiler-finder.ts
@@ -27,27 +27,56 @@ import https from 'https';
import path from 'path';
import {promisify} from 'util';
+import AWS from 'aws-sdk';
import fs from 'fs-extra';
import _ from 'underscore';
import urljoin from 'url-join';
+import {Language} from '../types/languages.interfaces';
+
import {InstanceFetcher} from './aws';
+import {CompileHandler} from './handlers/compile';
import {logger} from './logger';
+import {ClientOptionsHandler} from './options-handler';
+import {CompilerProps, RawPropertiesGetter} from './properties';
+import {PropertyGetter, PropertyValue, Widen} from './properties.interfaces';
const sleep = promisify(setTimeout);
+export type CompilerFinderArguments = {
+ rootDir: string;
+ env: string[];
+ hostname: string[];
+ port: number;
+ gitReleaseName: string;
+ releaseBuildNumber: string;
+ wantedLanguages: string | null;
+ doCache: boolean;
+ fetchCompilersFromRemote: boolean;
+ ensureNoCompilerClash: boolean;
+ suppressConsoleLog: boolean;
+};
+
/***
* Finds and initializes the compilers stored on the properties files
*/
export class CompilerFinder {
- /***
- * @param {CompileHandler} compileHandler
- * @param {CompilerProps} compilerProps
- * @param {propsFor} awsProps
- * @param {Object} args
- * @param {Object} optionsHandler
- */
- constructor(compileHandler, compilerProps, awsProps, args, optionsHandler) {
+ compilerProps: CompilerProps['get'];
+ ceProps: PropertyGetter;
+ awsProps: PropertyGetter;
+ args: CompilerFinderArguments;
+ compileHandler: CompileHandler;
+ languages: Record<string, Language>;
+ awsPoller: InstanceFetcher | null = null;
+ optionsHandler: ClientOptionsHandler;
+
+ constructor(
+ compileHandler: CompileHandler,
+ compilerProps: CompilerProps,
+ awsProps: PropertyGetter,
+ args: CompilerFinderArguments,
+ optionsHandler: ClientOptionsHandler,
+ ) {
this.compilerProps = compilerProps.get.bind(compilerProps);
this.ceProps = compilerProps.ceProps;
this.awsProps = awsProps;
@@ -95,7 +124,7 @@ export class CompilerFinder {
`${uriSchema}://${host}:${port}${apiPath}\n` +
`Status Code: ${statusCode}`,
);
- } else if (!/^application\/json/.test(contentType)) {
+ } else if (!contentType || !/^application\/json/.test(contentType)) {
error = new Error(
'Invalid content-type.\n' +
`Expected application/json but received ${contentType}`,
@@ -129,7 +158,7 @@ export class CompilerFinder {
return compiler;
});
resolve(compilers);
- } catch (e) {
+ } catch (e: any) {
logger.error(`Error parsing response from ${uri} '${str}': ${e.message}`);
reject(e);
}
@@ -154,7 +183,7 @@ export class CompilerFinder {
logger.info('Fetching instances from AWS');
const instances = await this.awsInstances();
return Promise.all(
- instances.map(instance => {
+ (instances.filter(instance => instance !== undefined) as AWS.EC2.Instance[]).map(instance => {
logger.info('Checking instance ' + instance.InstanceId);
const address = this.awsProps('externalTestMode', false)
? instance.PublicDnsName
@@ -164,13 +193,16 @@ export class CompilerFinder {
);
}
- async compilerConfigFor(langId, compilerId, parentProps) {
+ async compilerConfigFor(langId: string, compilerId: string, parentProps: RawPropertiesGetter) {
const base = `compiler.${compilerId}.`;
- function props(propName, def) {
+ function props(propName: string, defaultValue: undefined): PropertyValue;
+ function props<T extends PropertyValue>(propName: string, defaultValue: Widen<T>): typeof defaultValue;
+ function props<T extends PropertyValue>(propName: string, defaultValue?: unknown): T;
+ function props(propName: string, defaultValue?: unknown) {
const propsForCompiler = parentProps(langId, base + propName);
if (propsForCompiler !== undefined) return propsForCompiler;
- return parentProps(langId, propName, def);
+ return parentProps(langId, propName, defaultValue);
}
const ceToolsPath = props('ceToolsPath', './');
@@ -206,7 +238,7 @@ export class CompilerFinder {
if (envVarsString === '') {
return [];
}
- const arr = [];
+ const arr: [string, string][] = [];
for (const el of envVarsString.split(':')) {
const [env, setting] = el.split('=');
arr.push([env, setting]);
@@ -261,7 +293,7 @@ export class CompilerFinder {
notification: props('notification', ''),
isSemVer: isSemVer,
semver: semverVer,
- libsArr: this.getSupportedLibrariesArr(props, langId),
+ libsArr: this.getSupportedLibrariesArr(props),
tools: _.omit(this.optionsHandler.get().tools[langId], tool => tool.isCompilerExcluded(compilerId, props)),
unwiseOptions: props('unwiseOptions', '').split('|'),
hidden: props('hidden', false),
@@ -328,15 +360,15 @@ export class CompilerFinder {
}
async getCompilers() {
- const compilers = [];
+ const compilers: any[] = [];
_.each(this.getExes(), (exs, langId) => {
_.each(exs, exe => compilers.push(this.recurseGetCompilers(langId, exe, this.compilerProps)));
});
return Promise.all(compilers);
}
- ensureDistinct(compilers) {
- const ids = {};
+ ensureDistinct(compilers: any[]) {
+ const ids: Record<string, any> = {};
let foundClash = false;
_.each(compilers, compiler => {
if (!ids[compiler.id]) ids[compiler.id] = [];
@@ -372,14 +404,16 @@ export class CompilerFinder {
}
getExes() {
- const langToCompilers = this.compilerProps(this.languages, 'compilers', '', exs => _.compact(exs.split(':')));
+ const langToCompilers = this.compilerProps(this.languages, 'compilers', '', exs =>
+ _.compact((exs as string).split(':')),
+ );
this.addNdkExes(langToCompilers);
logger.info('Exes found:', langToCompilers);
return langToCompilers;
}
addNdkExes(langToCompilers) {
- const ndkPaths = this.compilerProps(this.languages, 'androidNdk');
+ const ndkPaths = this.compilerProps(this.languages, 'androidNdk') as unknown as Record<string, string>;
_.each(ndkPaths, (ndkPath, langId) => {
if (ndkPath) {
const toolchains = fs.readdirSync(`${ndkPath}/toolchains`);
diff --git a/lib/properties.ts b/lib/properties.ts
index 3075e2cdd..6dbb8c299 100644
--- a/lib/properties.ts
+++ b/lib/properties.ts
@@ -67,6 +67,8 @@ export function get(base: string, property: string, defaultValue?: unknown): unk
return result;
}
+export type RawPropertiesGetter = typeof get;
+
export function parseProperties(blob, name) {
const props = {};
for (const [index, lineOrig] of blob.split('\n').entries()) {
@@ -132,9 +134,9 @@ type LanguageDef = {
* Compiler property fetcher
*/
export class CompilerProps {
- private languages: Record<string, any>;
- private propsByLangId: Record<string, PropertyGetter>;
- private ceProps: any;
+ public readonly languages: Record<string, any>;
+ public readonly propsByLangId: Record<string, PropertyGetter>;
+ public readonly ceProps: PropertyGetter;
/***
* Creates a CompilerProps lookup function
@@ -149,6 +151,9 @@ export class CompilerProps {
_.each(this.languages, lang => (this.propsByLangId[lang.id] = propsFor(lang.id)));
}
+ $getInternal(base: string, property: string, defaultValue: undefined): PropertyValue;
+ $getInternal<T extends PropertyValue>(base: string, property: string, defaultValue: Widen<T>): typeof defaultValue;
+ $getInternal<T extends PropertyValue>(base: string, property: string, defaultValue?: PropertyValue): T;
$getInternal(langId: string, key: string, defaultValue: PropertyValue): PropertyValue {
const languagePropertyValue = this.propsByLangId[langId](key);
if (languagePropertyValue !== undefined) {
@@ -171,26 +176,58 @@ export class CompilerProps {
* @returns {*} Transformed value(s) found or fn(defaultValue)
*/
get(
- langs: string | LanguageDef[],
+ base: string | LanguageDef[] | Record<string, any>,
+ property: string,
+ defaultValue?: undefined,
+ fn?: undefined,
+ ): PropertyValue;
+ get<T extends PropertyValue>(
+ base: string | LanguageDef[] | Record<string, any>,
+ property: string,
+ defaultValue: Widen<T>,
+ fn?: undefined,
+ ): typeof defaultValue;
+ get<T extends PropertyValue>(
+ base: string | LanguageDef[] | Record<string, any>,
+ property: string,
+ defaultValue?: PropertyValue,
+ fn?: undefined,
+ ): T;
+
+ get<R>(
+ base: string | LanguageDef[] | Record<string, any>,
+ property: string,
+ defaultValue?: undefined,
+ fn?: (item: PropertyValue, language?: any) => R,
+ ): R;
+ get<T extends PropertyValue, R>(
+ base: string | LanguageDef[] | Record<string, any>,
+ property: string,
+ defaultValue: Widen<T>,
+ fn?: (item: PropertyValue, language?: any) => R,
+ ): typeof defaultValue | R;
+
+ get(
+ langs: string | LanguageDef[] | Record<string, any>,
key: string,
- defaultValue: PropertyValue,
- fn: (item: PropertyValue, language?: any) => PropertyValue = _.identity,
+ defaultValue?: PropertyValue,
+ fn?: (item: PropertyValue, language?: any) => unknown,
) {
- fn = fn || _.identity;
+ const map_fn = fn || _.identity;
if (_.isEmpty(langs)) {
- return fn(this.ceProps(key, defaultValue));
+ return map_fn(this.ceProps(key, defaultValue));
}
if (!_.isString(langs)) {
return _.chain(langs)
- .map(lang => [lang.id, fn(this.$getInternal(lang.id, key, defaultValue), lang)])
+ .map(lang => [lang.id, map_fn(this.$getInternal(lang.id, key, defaultValue), lang)])
.object()
.value();
} else {
if (this.propsByLangId[langs]) {
- return fn(this.$getInternal(langs, key, defaultValue), this.languages[langs]);
+ return map_fn(this.$getInternal(langs, key, defaultValue), this.languages[langs]);
} else {
logger.error(`Tried to pass ${langs} as a language ID`);
- return fn(defaultValue);
+ return map_fn(defaultValue);
}
}
}