improve device config loading
- support specifying device{,-list} config with config file name instead of config path - support loading mutliple device{,-list} configs at once. Previously, loading multiple device configs was supported only by passing a device-list config - parallelize config loading with promises
This commit is contained in:
parent
4503081dbf
commit
81adbb0c42
3 changed files with 71 additions and 14 deletions
|
@ -193,7 +193,7 @@ export default class GenerateFull extends Command {
|
||||||
args: { config: configPath },
|
args: { config: configPath },
|
||||||
} = this.parse(GenerateFull)
|
} = this.parse(GenerateFull)
|
||||||
|
|
||||||
let devices = await loadDeviceConfigs(configPath)
|
let devices = await loadDeviceConfigs([configPath])
|
||||||
|
|
||||||
await forEachDevice(
|
await forEachDevice(
|
||||||
devices,
|
devices,
|
||||||
|
|
|
@ -86,7 +86,7 @@ export default class GeneratePrep extends Command {
|
||||||
args: { config: configPath },
|
args: { config: configPath },
|
||||||
} = this.parse(GeneratePrep)
|
} = this.parse(GeneratePrep)
|
||||||
|
|
||||||
let devices = await loadDeviceConfigs(configPath)
|
let devices = await loadDeviceConfigs([configPath])
|
||||||
|
|
||||||
await forEachDevice(
|
await forEachDevice(
|
||||||
devices,
|
devices,
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
|
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
|
||||||
///<reference path="../util/jstypes.d.ts" />
|
///<reference path="../util/jstypes.d.ts" />
|
||||||
|
|
||||||
|
import { flags } from '@oclif/command'
|
||||||
import assert from 'assert'
|
import assert from 'assert'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
import { loadAndMergeConfig } from './config-loader'
|
import { loadAndMergeConfig } from './config-loader'
|
||||||
import { FilterMode, Filters, SerializedFilters } from './filters'
|
import { FilterMode, Filters, SerializedFilters } from './filters'
|
||||||
|
import { DEVICE_CONFIG_DIR } from './paths'
|
||||||
|
|
||||||
export enum ConfigType {
|
export enum ConfigType {
|
||||||
Device = 'device',
|
Device = 'device',
|
||||||
|
@ -113,30 +115,85 @@ const DEFAULT_CONFIG_BASE = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const DEVICE_CONFIG_FLAGS = {
|
||||||
|
devices: flags.string({
|
||||||
|
char: 'd',
|
||||||
|
description: `Device or DeviceList config paths or names`,
|
||||||
|
multiple: true,
|
||||||
|
default: ['all'],
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each string should refer to a Device or DeviceList config.
|
||||||
|
// There's two supported string formats: config path and config name from config dir (without .yml suffix),
|
||||||
|
// i.e. path/to/device_name.yml and device_name
|
||||||
|
export async function loadDeviceConfigs(strings: string[]) {
|
||||||
|
const configFileSuffix = '.yml'
|
||||||
|
|
||||||
|
let promises: Promise<DeviceConfig>[] = []
|
||||||
|
|
||||||
|
for (let string of strings) {
|
||||||
|
let configPath: string
|
||||||
|
if (string.endsWith(configFileSuffix)) {
|
||||||
|
configPath = string
|
||||||
|
} else {
|
||||||
|
configPath = path.join(DEVICE_CONFIG_DIR, string + configFileSuffix)
|
||||||
|
}
|
||||||
|
promises.push(...(await loadDeviceConfigsFromPath(configPath)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map is used to make sure there's at most one config per device
|
||||||
|
let map = new Map<string, DeviceConfig>()
|
||||||
|
|
||||||
|
for await (let config of promises) {
|
||||||
|
let key = config.device.name
|
||||||
|
if (map.get(key) !== undefined) {
|
||||||
|
console.warn(`loadDeviceConfigs: more than one config was passed for ${key}, only the last one will be used`)
|
||||||
|
}
|
||||||
|
map.set(key, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(map.values())
|
||||||
|
}
|
||||||
|
|
||||||
async function loadAndMergeDeviceConfig(configPath: string) {
|
async function loadAndMergeDeviceConfig(configPath: string) {
|
||||||
return await loadAndMergeConfig(configPath, DEFAULT_CONFIG_BASE)
|
return await loadAndMergeConfig(configPath, DEFAULT_CONFIG_BASE)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadDeviceConfigs(configPath: string) {
|
async function loadDeviceConfigFromPath(configPath: string): Promise<DeviceConfig> {
|
||||||
let merged = await loadAndMergeDeviceConfig(configPath)
|
let merged = await loadAndMergeDeviceConfig(configPath)
|
||||||
let { type } = merged
|
let type = merged.type
|
||||||
|
delete merged.type
|
||||||
|
assert(type === ConfigType.Device)
|
||||||
|
|
||||||
|
let res = merged as DeviceConfig
|
||||||
|
checkConfigName(res, configPath)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkConfigName(config: DeviceConfig, configPath: string) {
|
||||||
|
let configName = path.basename(configPath, '.yml')
|
||||||
|
let deviceName = config.device.name
|
||||||
|
assert(configName === deviceName, `config name doesn't match device name (${deviceName}): ${configPath}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadDeviceConfigsFromPath(configPath: string): Promise<Promise<DeviceConfig>[]> {
|
||||||
|
let merged = await loadAndMergeDeviceConfig(configPath)
|
||||||
|
let type = merged.type
|
||||||
delete merged.type
|
delete merged.type
|
||||||
|
|
||||||
if (type == ConfigType.Device) {
|
if (type === ConfigType.Device) {
|
||||||
let configName = path.basename(configPath, '.yml')
|
let res = merged as DeviceConfig
|
||||||
let deviceName = merged.device.name
|
checkConfigName(res, configPath)
|
||||||
assert(configName === deviceName, `config name doesn't match device name (${deviceName}): ${configPath}`)
|
return [Promise.resolve(res)]
|
||||||
return [merged as DeviceConfig]
|
} else if (type === ConfigType.DeviceList) {
|
||||||
}
|
|
||||||
if (type == ConfigType.DeviceList) {
|
|
||||||
// Load all the device configs
|
// Load all the device configs
|
||||||
let list = merged as DeviceListConfig
|
let list = merged as DeviceListConfig
|
||||||
let devices: DeviceConfig[] = []
|
let devices: Promise<DeviceConfig>[] = []
|
||||||
for (let devicePath of list.devices) {
|
for (let devicePath of list.devices) {
|
||||||
devicePath = path.resolve(path.dirname(configPath), devicePath)
|
devicePath = path.resolve(path.dirname(configPath), devicePath)
|
||||||
devices.push(await loadAndMergeDeviceConfig(devicePath))
|
devices.push(loadDeviceConfigFromPath(devicePath))
|
||||||
}
|
}
|
||||||
|
|
||||||
return devices
|
return devices
|
||||||
}
|
}
|
||||||
throw new Error(`Unknown config type ${type}`)
|
throw new Error(`Unknown config type ${type}`)
|
||||||
|
|
Loading…
Reference in a new issue