combo: convert instance and GitHub configs (#1820)

Summary:
This patch converts the `instanceConfig` and `github/config` parsers
from hand-written traversals to combinator-based structures. The
resulting code is much simpler and easier to read.

Test Plan:
Running the `sc2` CLI for `load` and `graph` still works in the happy
path, with the expected errors if keys in the config files are changed
to the wrong strings.

wchargin-branch: combo-instance-github
This commit is contained in:
William Chargin 2020-05-30 16:04:04 -07:00 committed by GitHub
parent 272af9db38
commit 109ebb0417
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 46 deletions

View File

@ -1,5 +1,6 @@
// @flow // @flow
import * as Combo from "../util/combo";
import {CliPlugin} from "./cliPlugin"; import {CliPlugin} from "./cliPlugin";
import {bundledPlugins as getAllBundledPlugins} from "./bundledPlugins"; import {bundledPlugins as getAllBundledPlugins} from "./bundledPlugins";
@ -19,37 +20,25 @@ export type RawInstanceConfig = {|
// dependencies. // dependencies.
export type BundledPluginSpec = string; export type BundledPluginSpec = string;
type JsonObject = const parser: Combo.Parser<InstanceConfig> = (() => {
| string const C = Combo;
| number function makePluginMap(bundledPluginNames) {
| boolean
| null
| JsonObject[]
| {[string]: JsonObject};
export function parse(raw: JsonObject): InstanceConfig {
if (raw == null || typeof raw !== "object" || Array.isArray(raw)) {
throw new Error("bad config: " + JSON.stringify(raw));
}
const {bundledPlugins: rawBundledPlugins} = raw;
if (!Array.isArray(rawBundledPlugins)) {
console.warn(JSON.stringify(raw));
throw new Error(
"bad bundled plugins: " + JSON.stringify(rawBundledPlugins)
);
}
const allBundledPlugins = getAllBundledPlugins(); const allBundledPlugins = getAllBundledPlugins();
const bundledPlugins = new Map(); const bundledPlugins = new Map();
for (const name of rawBundledPlugins) { for (const name of bundledPluginNames) {
if (typeof name !== "string") {
throw new Error("bad bundled plugin: " + JSON.stringify(name));
}
const plugin = allBundledPlugins[name]; const plugin = allBundledPlugins[name];
if (plugin == null) { if (plugin == null) {
throw new Error("bad bundled plugin: " + JSON.stringify(name)); throw new Error("bad bundled plugin: " + JSON.stringify(name));
} }
bundledPlugins.set(name, plugin); bundledPlugins.set(name, plugin);
} }
const result = {bundledPlugins}; return bundledPlugins;
return result; }
return C.object({
bundledPlugins: C.fmap(C.array(C.string), makePluginMap),
});
})();
export function parse(raw: Combo.JsonObject): InstanceConfig {
return parser.parseOrThrow(raw);
} }

View File

@ -1,5 +1,6 @@
// @flow // @flow
import * as Combo from "../../util/combo";
import {type RepoId, stringToRepoId} from "./repoId"; import {type RepoId, stringToRepoId} from "./repoId";
export type GithubConfig = {| export type GithubConfig = {|
@ -20,19 +21,16 @@ type JsonObject =
| JsonObject[] | JsonObject[]
| {[string]: JsonObject}; | {[string]: JsonObject};
export function parse(raw: JsonObject): GithubConfig { const parser: Combo.Parser<GithubConfig> = (() => {
if (raw == null || typeof raw !== "object" || Array.isArray(raw)) { const C = Combo;
throw new Error("bad config: " + JSON.stringify(raw)); return C.object({
} repoIds: C.rename(
const {repositories} = raw; "repositories",
if (!Array.isArray(repositories)) { C.array(C.fmap(C.string, stringToRepoId))
throw new Error("bad repositories: " + JSON.stringify(repositories)); ),
}
const repoIds = repositories.map((x) => {
if (typeof x !== "string") {
throw new Error("bad repository: " + JSON.stringify(x));
}
return stringToRepoId(x);
}); });
return {repoIds}; })();
export function parse(raw: Combo.JsonObject): GithubConfig {
return parser.parseOrThrow(raw);
} }