gitpod/components/gitpod-protocol/src/gitpod-file-parser.ts
2022-03-14 21:42:21 +05:30

66 lines
2.2 KiB
TypeScript

/**
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
* Licensed under the GNU Affero General Public License (AGPL).
* See License-AGPL.txt in the project root for license information.
*/
import { injectable } from "inversify";
import * as yaml from "js-yaml";
import * as Ajv from "ajv";
import { log } from "./util/logging";
import { WorkspaceConfig, PortRangeConfig } from "./protocol";
export type MaybeConfig = WorkspaceConfig | undefined;
const schema = require("../data/gitpod-schema.json");
const validate = new Ajv().compile(schema);
const defaultParseOptions = {
acceptPortRanges: false,
};
export interface ParseResult {
config: WorkspaceConfig;
parsedConfig?: WorkspaceConfig;
validationErrors?: string[];
}
@injectable()
export class GitpodFileParser {
public parse(content: string, parseOptions = {}, defaultConfig: WorkspaceConfig = {}): ParseResult {
const options = {
...defaultParseOptions,
...parseOptions,
};
try {
const parsedConfig = yaml.safeLoad(content) as any;
validate(parsedConfig);
const validationErrors = validate.errors ? validate.errors.map((e) => e.message || e.keyword) : undefined;
if (validationErrors && validationErrors.length > 0) {
return {
config: defaultConfig,
parsedConfig,
validationErrors,
};
}
const overrides = {} as any;
if (!options.acceptPortRanges && Array.isArray(parsedConfig.ports)) {
overrides.ports = parsedConfig.ports.filter((port: any) => !PortRangeConfig.is(port));
}
return {
config: {
...defaultConfig,
...parsedConfig,
...overrides,
},
parsedConfig,
};
} catch (err) {
log.error("Unparsable Gitpod configuration", err, { content });
return {
config: defaultConfig,
validationErrors: ["Unparsable Gitpod configuration: " + err.toString()],
};
}
}
}