diff --git a/packages/core/package.json b/packages/core/package.json index 7951080a..c4aaf358 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -33,14 +33,15 @@ "dependencies": { "caller": "^1.0.1", "debug": "^3.0.0", + "gert": "^2.0.0", + "gert-topo-sort": "^1.0.0", "glob": "^7.1.1", "inversify": "^4.3.0", "inversify-logger-middleware": "^3.0.0", "js-yaml": "^3.8.1", "lodash": "^4.17.4", "shortstop": "^1.0.3", - "shortstop-handlers": "^1.0.1", - "topo": "^2.0.2" + "shortstop-handlers": "^1.0.1" }, "devDependencies": { "@types/debug": "^0.0.30", diff --git a/packages/core/src/plugin-list.ts b/packages/core/src/plugin-list.ts index ceb11816..a3e853b9 100644 --- a/packages/core/src/plugin-list.ts +++ b/packages/core/src/plugin-list.ts @@ -6,7 +6,8 @@ import { } from './interfaces'; import { METADATA_KEY, ERRORS_MSGS } from './constants'; import * as _ from 'lodash'; -import * as Topo from 'topo'; +import { Graph } from 'gert'; +import * as TopoSort from 'gert-topo-sort'; export class PluginList { private _plugins: GabliamPluginDefinition[] = []; @@ -25,35 +26,61 @@ export class PluginList { } sort() { - const treePlugin = new Topo(); - + const vertices: { [k: string]: string[] } = {}; for (const plugin of this._plugins) { - const after = []; - const before = []; + const orderedPlugin = [plugin.name]; if (plugin.dependencies) { - for (const dep of plugin.dependencies) { - if (!this.has(dep.name)) { + for (const deps of plugin.dependencies) { + if (!this.has(deps.name)) { throw new Error( - `The plugin ${plugin.name} need the plugin ${dep.name}}` + `The plugin ${plugin.name} need the plugin ${deps.name}}` ); } - switch (dep.order) { - case 'before': - before.unshift(dep.name); - break; + switch (deps.order) { case 'after': - after.push(dep.name); + orderedPlugin.unshift(deps.name); + break; + case 'before': + orderedPlugin.push(deps.name); break; } } } - treePlugin.add(plugin.name, { after, before }); + while (orderedPlugin.length && orderedPlugin[0] !== plugin.name) { + const name = orderedPlugin.shift()!; + const index = + orderedPlugin.indexOf(plugin.name) === orderedPlugin.length + ? orderedPlugin.length + : orderedPlugin.indexOf(plugin.name) + 1; + const toAdd = _.without(orderedPlugin.slice(0, index), name); + if (!vertices[name]) { + vertices[name] = []; + } + + vertices[name].push(...toAdd); + vertices[name] = _.uniq(vertices[name]); + } + + if (!vertices[plugin.name]) { + vertices[plugin.name] = []; + } + + vertices[plugin.name].push( + ..._.without(orderedPlugin.slice(1), plugin.name) + ); + vertices[plugin.name] = _.uniq(vertices[plugin.name]); } - const sortedPlugins = treePlugin.nodes; - const listPlugin = sortedPlugins.map( + const graph = new Graph({ + directed: true, + vertices + }); + + // Rewrite listPlugin + const listPlugin = TopoSort(graph).map( p => this.findByName(p)! ); + this._plugins = listPlugin; } diff --git a/packages/core/src/typings/gert.d.ts b/packages/core/src/typings/gert.d.ts new file mode 100644 index 00000000..ca6437bf --- /dev/null +++ b/packages/core/src/typings/gert.d.ts @@ -0,0 +1,18 @@ +declare module 'gert' { + interface GraphOptions { + directed: boolean; + vertices: { [k: string]: string[] }; + } + export class Graph { + constructor(options: GraphOptions); + } +} + +declare module 'gert-topo-sort' { + import gert = require('gert'); + + type Gts = (graph: gert.Graph) => string[]; + const gts: Gts; + + export = gts; +} diff --git a/packages/core/src/typings/topo.d.ts b/packages/core/src/typings/topo.d.ts deleted file mode 100644 index 693075a4..00000000 --- a/packages/core/src/typings/topo.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -declare module 'topo' { - class Topo { - nodes: any[]; - - constructor(); - - add(nodes: any | any[], options?: Topo.AddOptions): void; - - merge(others: any | any[]): any; - } - - namespace Topo { - interface AddOptions { - group?: string; - - before?: string | string[]; - - after?: string | string[]; - - sort?: number; - } - } - - export = Topo; -} diff --git a/packages/core/yarn.lock b/packages/core/yarn.lock index 905ac4cc..abe11c15 100644 --- a/packages/core/yarn.lock +++ b/packages/core/yarn.lock @@ -1540,6 +1540,17 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +gert-topo-sort@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gert-topo-sort/-/gert-topo-sort-1.0.0.tgz#e63d78cb134576c43cda2116f1689bce93a8dac0" + +gert@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gert/-/gert-2.0.0.tgz#634c649751ddd4b6f1aefb46d31f8057a1a62b71" + dependencies: + hoek "^2.16.3" + joi "^6.9.1" + get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" @@ -1836,7 +1847,7 @@ hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" -hoek@2.x.x: +hoek@2.x.x, hoek@^2.16.3: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" @@ -4359,7 +4370,7 @@ topo@1.x.x: dependencies: hoek "2.x.x" -topo@2.x.x, topo@^2.0.2: +topo@2.x.x: version "2.0.2" resolved "https://registry.yarnpkg.com/topo/-/topo-2.0.2.tgz#cd5615752539057c0dc0491a621c3bc6fbe1d182" dependencies: