Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: plugin has own excluded #129

Merged
merged 8 commits into from
Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export const DEFAULT_EXCLUDES = [
'LICENSE'
];

export const DEFAULT_EXTENSIONS = ['.js', '.json', '.node', '.yaml'];

export const FRAMEWORK_PATTERN = 'framework.*';
export const PLUGIN_CONFIG_PATTERN = 'plugin.*';
export const CONFIG_PATTERN = 'config.*';
Expand Down
41 changes: 39 additions & 2 deletions src/framework/handler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import path from 'path';
import ConfigurationHandler, { ConfigObject } from '../configuration';
import { ManifestItem } from '../types';

import { ManifestItem, Metadata } from '../types';
import { exisis } from '../utils/fs';
import { loadMetaFile } from '../utils/load_meta_file';
export interface FrameworkConfig {
path?: string,
package?: string
Expand Down Expand Up @@ -33,4 +34,40 @@ export class FrameworkHandler {
throw new Error(`load framework faild: ${err}, framework config: ${JSON.stringify(config)}`);
}
}
static async checkAndLoadMetadata(frameworkDir: string): Promise<Metadata>{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

和 Plugin 的好像重复实现了?

// check import path
if (!await exisis(frameworkDir)) {
throw new Error(`load framework import path ${frameworkDir} is not exists.`);
}

let find = false;
const fileNameList = [
'meta.yaml',
'meta.yml',
'meta.json',
];
let metadata;
for (const fileName of fileNameList) {
const metaFilePath = path.resolve(frameworkDir, fileName);
try {
if (!await exisis(metaFilePath)) {
continue;
}
metadata = await loadMetaFile({
path: metaFilePath,
extname: path.extname(metaFilePath),
filename: fileName,
});
find = true;
break;
} catch (e) {
throw new Error(`load framework metadata <${frameworkDir}> failed, err: ${e}`);
}
}

if (!find) {
throw new Error(`load framework import path ${frameworkDir} can't find meta file.`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个应该会造成无 meta.yaml 的 Framework 直接报错,会是 Breaking Change cc @hyj1991

}
return metadata;
}
}
5 changes: 2 additions & 3 deletions src/plugin/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { Metadata } from '../types';
export enum PluginType {
simple = 'simple',
module = 'module',
}

export interface PluginMetadata {
name: string;
export interface PluginMetadata extends Metadata {
dependencies?: PluginDependencyItem[];
type?: PluginType;
configDir?: string
}

export interface PluginDependencyItem {
Expand Down
59 changes: 44 additions & 15 deletions src/scanner/scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@ import {
ARTUS_DEFAULT_CONFIG_ENV,
DEFAULT_CONFIG_DIR,
DEFAULT_EXCLUDES,
DEFAULT_EXTENSIONS,
DEFAULT_LOADER_LIST_WITH_ORDER,
LOADER_NAME_META,
} from '../constant';
import { LoaderFactory, Manifest, ManifestItem } from '../loader';
import { Metadata } from '../types';
import { ScannerOptions, WalkOptions } from './types';
import ConfigurationHandler, { ConfigObject } from '../configuration';
import { FrameworkConfig, FrameworkHandler } from '../framework';
import { BasePlugin, PluginFactory } from '../plugin';
import { ScanUtils } from './utils';

export class Scanner {
private moduleExtensions = ['.js', '.json', '.node'];
private options: ScannerOptions;
private itemMap: Map<string, ManifestItem[]> = new Map();
private tmpConfigStore: Map<string, ConfigObject[]> = new Map();
Expand All @@ -32,8 +33,8 @@ export class Scanner {
configDir: DEFAULT_CONFIG_DIR,
loaderListGenerator: (defaultLoaderList: string[]) => defaultLoaderList,
...options,
excluded: DEFAULT_EXCLUDES.concat(options.excluded ?? []),
extensions: [...new Set(this.moduleExtensions.concat(options.extensions ?? [], ['.yaml']))],
exclude: [...new Set(DEFAULT_EXCLUDES.concat(options.exclude ?? []))],
extensions: [...new Set(DEFAULT_EXTENSIONS.concat(options.extensions ?? []))],
};
}

Expand Down Expand Up @@ -94,10 +95,11 @@ export class Scanner {
// 1. scan all file in framework
const frameworkDirs = await this.getFrameworkDirs(config.framework, root, env);
for (const frameworkDir of frameworkDirs) {
await this.walk(frameworkDir, this.formatWalkOptions('framework', frameworkDir));
const frameworkMetadata = await FrameworkHandler.checkAndLoadMetadata(frameworkDir);
const frameworkOptions = this.formatWalkOptions('framework', frameworkDir, frameworkDir, frameworkMetadata);
await this.walk(frameworkDir, frameworkOptions);
}


// 2. scan all file in plugin
if (this.tmpConfigStore.has(env)) {
const configList = this.tmpConfigStore.get(env) ?? [];
Expand All @@ -108,10 +110,8 @@ export class Scanner {
for (const plugin of pluginSortedList) {
if (!plugin.enable) continue;
this.setPluginMeta(plugin);
await this.walk(
plugin.importPath,
this.formatWalkOptions('plugin', plugin.importPath, plugin.name, plugin.metadata.configDir)
);
const pluginOpts = this.formatWalkOptions('plugin', plugin.importPath, plugin.name, plugin.metadata as Metadata);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果是 extends 的 interface,不需要 as 吧

await this.walk(plugin.importPath, pluginOpts);
}

// 3. scan all file in app
Expand Down Expand Up @@ -150,9 +150,9 @@ export class Scanner {
const container = new Container(ArtusInjectEnum.DefaultContainerName);
container.set({ type: ConfigurationHandler });
const loaderFactory = LoaderFactory.create(container);
const configItemList: (ManifestItem|null)[] = await Promise.all(configFileList.map(async filename => {
const configItemList: (ManifestItem | null)[] = await Promise.all(configFileList.map(async filename => {
const extname = path.extname(filename);
if (ScanUtils.isExclude(filename, extname, this.options.excluded, this.options.extensions)) {
if (ScanUtils.isExclude(filename, extname, this.options.exclude, this.options.extensions)) {
return null;
}
let loader = await loaderFactory.findLoaderName({
Expand Down Expand Up @@ -215,22 +215,51 @@ export class Scanner {
return await this.getFrameworkDirs(configInFramework.framework, frameworkBaseDir, env, dirs);
}

private formatWalkOptions(source: string, baseDir: string, unitName?: string, configDir?: string): WalkOptions {
private formatWalkOptions(source: string, baseDir: string, unitName?: string, metadata?: Metadata): WalkOptions {
const commonOptions = {
extensions: this.options.extensions,
excluded: this.options.excluded,
exclude: this.options.exclude,
itemMap: this.itemMap,
};

unitName ??= baseDir;
configDir ??= this.options.configDir;
const configDir = this.options.configDir;

return Object.assign({}, commonOptions, {
let result: WalkOptions = Object.assign({}, commonOptions, {
source,
baseDir,
unitName,
configDir,
});
// metadata takes priority
if (metadata) {
result = this.amendOptions(result, metadata);
}
return result;
}

private amendOptions(walkOptions: WalkOptions, metadata): WalkOptions {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

昨天不是说把这个逻辑直接放在 formatWalkOptions 里?增加 “amend” 的意义在哪,这就是 formatWalkOptions 的职责吧

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是啊,这不是在formatWalkOptions里面调用的嘛

// plugin/framework exclude take priority over user app's
if (metadata?.exclude) {
walkOptions.exclude = DEFAULT_EXCLUDES.concat(metadata.exclude);
} else {
walkOptions.exclude = DEFAULT_EXCLUDES;
}

// plugin/framework extensions take priority over user app's
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

先去掉吧,这是社区项目,留太多无用注释不好

// if (metadata?.extensions) {
// walkOptions.extensions = DEFAULT_EXTENSIONS.concat(metadata.extensions);
// } else {
// walkOptions.extensions = DEFAULT_EXTENSIONS;
// }

// plugin/framework configDir take priority over user app's
if (metadata?.configDir) {
walkOptions.configDir = metadata.configDir;
} else {
walkOptions.configDir = DEFAULT_CONFIG_DIR;
}
return walkOptions;
}

private getItemsFromMap(relative: boolean, appRoot: string): ManifestItem[] {
Expand Down
4 changes: 2 additions & 2 deletions src/scanner/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export interface ScannerOptions {
extensions: string[];
needWriteFile: boolean;
useRelativePath: boolean;
excluded: string[];
exclude: string[];
configDir: string;
envs?: string[];
loaderListGenerator: (defaultLoaderList: string[]) => (string | typeof BaseLoader)[];
Expand All @@ -16,7 +16,7 @@ export interface WalkOptions {
baseDir: string;
configDir: string;
extensions: string[];
excluded: string[];
exclude: string[];
itemMap: Map<string, ManifestItem[]>;
unitName?: string;
}
Expand Down
8 changes: 4 additions & 4 deletions src/scanner/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class ScanUtils {
for (const item of items) {
const realPath = path.resolve(root, item);
const extname = path.extname(realPath);
if (this.isExclude(item, extname, options.excluded, options.extensions)) {
if (this.isExclude(item, extname, options.exclude, options.extensions)) {
continue;
}
const itemStat = await fs.stat(realPath);
Expand Down Expand Up @@ -78,10 +78,10 @@ export class ScanUtils {
}

static isExclude(filename: string, extname: string,
excluded: string[], extensions: string[]): boolean {
exclude: string[], extensions: string[]): boolean {
let result = false;
if (!result && excluded) {
result = isMatch(filename, excluded);
if (exclude) {
result = isMatch(filename, exclude);
}

if (!result && extname) {
Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,11 @@ export interface TriggerType {
initContext(...args): Promise<BaseContext>;
startPipeline(...args): Promise<void>;
}
export interface Metadata {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

命名太泛了?

name: string;
exclude?: string[];
extensions?: string[];
configDir?: string
}

export * from './loader/types';
1 change: 1 addition & 0 deletions test/fixtures/app_koa_with_ts/src/redis_plugin/meta.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
name: redis
exclude: ['not_to_be_scanned_file.ts', 'not_to_be_scanned_dir']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

缺 glob 形式的验证,可以后续补充

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'reflect-metadata';
import { Injectable, ScopeEnum } from '@artus/injection';

@Injectable({
scope: ScopeEnum.EXECUTION
})
export default class NotToBeScannedModule {
async index () {
return {
status: 200,
content: 'Hello Artus'
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'reflect-metadata';
import { Injectable, ScopeEnum } from '@artus/injection';

@Injectable({
scope: ScopeEnum.EXECUTION
})
export default class NotToBeScannedController {
async index () {
return {
status: 200,
content: 'Hello Artus'
};
}
}
1 change: 1 addition & 0 deletions test/fixtures/frameworks/bar/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name: bar
1 change: 1 addition & 0 deletions test/fixtures/frameworks/layer/foo/foo1/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name: "foo1"
1 change: 1 addition & 0 deletions test/fixtures/frameworks/layer/foo/foo2/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name: "foo2"
5 changes: 5 additions & 0 deletions test/scanner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ describe('test/scanner.test.ts', () => {
// console.log('manifest', manifest);
expect(manifest.items.length).toBe(11);

const excludes = manifest.items.filter(one => {
return ['not_to_be_scanned_file.ts', 'module.ts'].includes(one.filename)
})
expect(excludes).toHaveLength(0);

expect(manifest.items.filter(item => item.loader === 'plugin-config').length).toBe(0);
expect(manifest.items.filter(item => item.loader === 'plugin-meta').length).toBe(1);
expect(manifest.items.filter(item => item.loader === 'exception').length).toBe(1);
Expand Down