Skip to content

Commit

Permalink
refactor: merge plugin config when load because of plugin preset (#272)
Browse files Browse the repository at this point in the history
  • Loading branch information
noahziheng authored Jan 29, 2024
1 parent a2e5f6d commit 4435a71
Show file tree
Hide file tree
Showing 19 changed files with 220 additions and 171 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,3 @@ lib

# OSX
.DS_Store

!test/fixtures/frameworks/layer/foo/foo2/node_modules
18 changes: 10 additions & 8 deletions src/configuration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import { mergeConfig } from '../loader/utils/merge';
import compatibleRequire from '../utils/compatible_require';

export type ConfigObject = Record<string, any>;
export type FrameworkObject = { path: string; env: string };
export type PackageObject = ConfigObject;
export type FrameworkOptions = { env: string; unitName: string };

@Injectable()
export default class ConfigurationHandler {
Expand All @@ -19,28 +17,32 @@ export default class ConfigurationHandler {
return env;
}

public configStore: Map<string, ConfigObject> = new Map();
public configStore: Record<string, ConfigObject> = {};

@Inject()
private container: Container;

getMergedConfig(): ConfigObject {
return this.mergeConfigByStore(this.configStore);
}

mergeConfigByStore(store: Record<string, ConfigObject>): ConfigObject {
let envList: string[] = this.container.get(ArtusInjectEnum.EnvList, { noThrow: true });
if (!envList) {
envList = process.env[ARTUS_SERVER_ENV] ? [process.env[ARTUS_SERVER_ENV]] : [ARTUS_DEFAULT_CONFIG_ENV.DEV];
}
const defaultConfig = this.configStore.get(ARTUS_DEFAULT_CONFIG_ENV.DEFAULT) ?? {};
const envConfigList = envList.map(currentEnv => (this.configStore.get(currentEnv) ?? {}));
const defaultConfig = store[ARTUS_DEFAULT_CONFIG_ENV.DEFAULT] ?? {};
const envConfigList = envList.map(currentEnv => (store[currentEnv] ?? {}));
return mergeConfig(defaultConfig, ...envConfigList);
}

clearStore(): void {
this.configStore.clear();
this.configStore = {};
}

setConfig(env: string, config: ConfigObject) {
const storedConfig = this.configStore.get(env) ?? {};
this.configStore.set(env, mergeConfig(storedConfig, config));
const storedConfig = this.configStore[env] ?? {};
this.configStore[env] = mergeConfig(storedConfig, config);
}

async setConfigByFile(fileItem: ManifestItem) {
Expand Down
1 change: 0 additions & 1 deletion src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export const DEFAULT_LOADER_LIST_WITH_ORDER = [
'exception',
'exception-filter',
'plugin-meta',
'framework-config',
'package-json',
'module',
'lifecycle-hook-unit',
Expand Down
28 changes: 17 additions & 11 deletions src/loader/factory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as path from 'path';
import { Container, Injectable, Inject, ScopeEnum } from '@artus/injection';
import { DEFAULT_LOADER, LOADER_NAME_META, DEFAULT_LOADER_LIST_WITH_ORDER, DEFAULT_APP_REF } from '../constant';
import { DEFAULT_LOADER, LOADER_NAME_META, DEFAULT_LOADER_LIST_WITH_ORDER, DEFAULT_APP_REF, ARTUS_DEFAULT_CONFIG_ENV } from '../constant';
import {
Manifest,
ManifestItem,
Expand All @@ -10,8 +10,9 @@ import {
import ConfigurationHandler from '../configuration';
import { LifecycleManager } from '../lifecycle';
import LoaderEventEmitter, { LoaderEventListener } from './loader_event';
import { PluginConfigItem, PluginFactory } from '../plugin';
import { PluginConfig, PluginFactory } from '../plugin';
import { Logger, LoggerType } from '../logger';
import { mergeConfig } from './utils/merge';

@Injectable({
scope: ScopeEnum.SINGLETON,
Expand Down Expand Up @@ -69,15 +70,20 @@ export class LoaderFactory {
// Manifest Version 2 is supported mainly

// Merge plugin config with ref
for (const [env, pluginConfig] of Object.entries(manifest.pluginConfig ?? {})) {
this.configurationHandler.setConfig(env, {
plugin: pluginConfig,
});
}
const mergedPluginConfig: Record<string, PluginConfigItem> = Object.assign(
{},
this.configurationHandler.getMergedConfig()?.plugin ?? {},
); // shallow copy to avoid side effect of writing metadata
const mergeRef = (refName: string) => {
if (!refName || !manifest.refMap?.[refName]) {
return {};
}
const pluginConfig = this.configurationHandler.mergeConfigByStore(manifest.refMap[refName].pluginConfig ?? {});
return mergeConfig(...Object.values(pluginConfig).map(({ refName }) => mergeRef(refName)).concat(pluginConfig));
};
const mergedPluginConfig = mergeConfig(manifest.extraPluginConfig ?? {}, ...[
...Object.values(manifest.extraPluginConfig ?? {}).map(({ refName }) => refName),
DEFAULT_APP_REF,
].map(mergeRef)) as PluginConfig;
this.configurationHandler.setConfig(ARTUS_DEFAULT_CONFIG_ENV.DEFAULT, {
plugin: mergedPluginConfig,
}); // For compatible
for (const [pluginName, pluginConfigItem] of Object.entries(mergedPluginConfig)) {
const refItem = manifest.refMap[pluginConfigItem.refName];
if (!refItem) {
Expand Down
5 changes: 0 additions & 5 deletions src/loader/impl/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,6 @@ class ConfigLoader implements Loader {
async load(item: ManifestItem) {
const { namespace, env } = getConfigMetaFromFilename(item.filename);
let configObj = await this.loadConfigFile(item);
// if (namespace === 'plugin') {
// configObj = {
// plugin: await PluginFactory.formatPluginConfig(configObj, item),
// };
// } else
if (namespace) {
configObj = {
[namespace]: configObj,
Expand Down
3 changes: 2 additions & 1 deletion src/loader/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ export interface RefMapItem {
relativedPath?: string;
packageVersion?: string;
pluginMetadata?: PluginMetadata;
pluginConfig: PluginConfigEnvMap;
items: ManifestItem[];
}
// Key: RefName => RefMapItem
export type RefMap = Record<string, RefMapItem>;

export interface Manifest {
version: '2';
pluginConfig: PluginConfigEnvMap;
refMap: RefMap;
extraPluginConfig?: PluginConfig;
}

export interface ManifestItem<LoaderState = unknown> extends Record<string, any> {
Expand Down
29 changes: 13 additions & 16 deletions src/scanner/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@ import path from 'path';
import * as fs from 'fs/promises';
import { ScannerOptions, ScanTaskItem, WalkOptions } from './types';
import { existsAsync, getPackageVersion, isExclude, isPluginAsync, loadConfigItemList, resolvePluginConfigItemRef } from './utils';
import { findLoader, Manifest, ManifestItem, PluginConfigEnvMap, RefMap, RefMapItem } from '../loader';
import { findLoader, Manifest, ManifestItem, RefMap, RefMapItem } from '../loader';
import { PluginConfig, PluginMetadata } from '../plugin';
import { mergeConfig } from '../loader/utils/merge';
import { loadMetaFile } from '../utils/load_meta_file';
import { ARTUS_DEFAULT_CONFIG_ENV, DEFAULT_APP_REF, PLUGIN_META_FILENAME } from '../constant';
import { DEFAULT_APP_REF, PLUGIN_META_FILENAME } from '../constant';
import { Application } from '../types';
import { ArtusApplication } from '../application';

export class ScanTaskRunner {
private waitingTaskMap: Map<string, ScanTaskItem[]> = new Map(); // Key is pluginName, waiting to detect enabled
private enabledPluginSet: Set<string> = new Set(); // Key is pluginName
private pluginConfigMap: PluginConfigEnvMap = {};
private extraPluginConfig: PluginConfig = {};
private refMap: RefMap = {};
private taskQueue: ScanTaskItem[] = [];
private app: Application;
Expand Down Expand Up @@ -99,14 +98,13 @@ export class ScanTaskRunner {
public async handlePluginConfig(
pluginConfig: PluginConfig,
basePath: string,
env: string = ARTUS_DEFAULT_CONFIG_ENV.DEFAULT,
): Promise<void> {
const tPluginConfig: PluginConfig = {};
): Promise<PluginConfig> {
const res: PluginConfig = {};
for (const [pluginName, pluginConfigItem] of Object.entries(pluginConfig)) {
// Set temp pluginConfig in manifest
tPluginConfig[pluginName] = {};
res[pluginName] = {};
if (pluginConfigItem.enable !== undefined) {
tPluginConfig[pluginName].enable = pluginConfigItem.enable;
res[pluginName].enable = pluginConfigItem.enable;
}
if (pluginConfigItem.enable) {
this.enabledPluginSet.add(pluginName);
Expand All @@ -118,7 +116,7 @@ export class ScanTaskRunner {
if (!ref?.name) {
continue;
}
tPluginConfig[pluginName].refName = ref.name;
res[pluginName].refName = ref.name;
// Generate and push scan task
const curRefTask: ScanTaskItem = {
curPath: ref.path,
Expand All @@ -140,9 +138,7 @@ export class ScanTaskRunner {
this.waitingTaskMap.set(pluginName, waitingTaskList);
}
}
// Reverse Merge, The prior of top-level(exists) is higher
const existsPluginConfig = this.pluginConfigMap[env] ?? {};
this.pluginConfigMap[env] = mergeConfig(tPluginConfig, existsPluginConfig) as PluginConfig;
return res;
}


Expand Down Expand Up @@ -195,6 +191,7 @@ export class ScanTaskRunner {
const refItem: RefMapItem = {
relativedPath,
packageVersion,
pluginConfig: {},
items: [],
};

Expand All @@ -217,7 +214,7 @@ export class ScanTaskRunner {
if (!pluginConfig) {
continue;
}
await this.handlePluginConfig(pluginConfig, basePath, env);
refItem.pluginConfig[env] = await this.handlePluginConfig(pluginConfig, basePath);
}

if (this.options.useRelativePath) {
Expand All @@ -233,7 +230,7 @@ export class ScanTaskRunner {
public async runAll(): Promise<void> {
// Add Task of options.plugin
if (this.options.plugin) {
await this.handlePluginConfig(this.options.plugin, this.root);
this.extraPluginConfig = await this.handlePluginConfig(this.options.plugin, this.root);
}

// Add Root Task(make it as top/start)
Expand All @@ -253,8 +250,8 @@ export class ScanTaskRunner {
public dump(): Manifest {
return {
version: '2',
pluginConfig: this.pluginConfigMap,
refMap: this.refMap,
extraPluginConfig: this.extraPluginConfig,
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/scanner/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const loadConfigItemList = async <T = ConfigObject>(configItemList: Manif
}

// Use temp Map to store config
const configEnvMap: Map<string, T> = new Map();
const configEnvMap: Record<string, T> = {};
const stashedConfigStore = app.configurationHandler.configStore;
app.configurationHandler.configStore = configEnvMap;

Expand All @@ -65,7 +65,7 @@ export const loadConfigItemList = async <T = ConfigObject>(configItemList: Manif
// Restore config store
app.configurationHandler.configStore = stashedConfigStore;

return Object.fromEntries(configEnvMap.entries());
return configEnvMap;
};

export const resolvePluginConfigItemRef = async (
Expand Down
Loading

0 comments on commit 4435a71

Please sign in to comment.