chore(command): set command handle by ipc server or not (#2660)
* chore: tmp commit * feat: app command * chore: return error when not handle by ipc server * chore: command handle by ipc server * chore: api name * Update pm.ts --------- Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
4fffa07998
commit
630c6f2d79
43
packages/core/server/src/__tests__/app-command.test.ts
Normal file
43
packages/core/server/src/__tests__/app-command.test.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { DataTypes, mockDatabase } from '@nocobase/database';
|
||||||
|
import Application, { ApplicationOptions } from '../application';
|
||||||
|
|
||||||
|
const mockServer = (options?: ApplicationOptions) => {
|
||||||
|
return new Application({
|
||||||
|
database: mockDatabase(),
|
||||||
|
acl: false,
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('app command', () => {
|
||||||
|
let app: Application;
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
if (app) {
|
||||||
|
await app.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
app = mockServer();
|
||||||
|
await app.load();
|
||||||
|
await app.install();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should test command should handle by IPC Server or not', () => {
|
||||||
|
app.command('testaa').ipc();
|
||||||
|
app.command('testbb');
|
||||||
|
|
||||||
|
expect(app.cli.parseHandleByIPCServer(['node', 'cli', 'nocobase', 'testaa'])).toBeTruthy();
|
||||||
|
expect(app.cli.parseHandleByIPCServer(['node', 'cli', 'nocobase', 'testbb'])).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should test sub command should handle by IPC Server or not', () => {
|
||||||
|
const subParent = app.command('subparent');
|
||||||
|
subParent.command('testaa').ipc();
|
||||||
|
subParent.command('testbb');
|
||||||
|
|
||||||
|
expect(app.cli.parseHandleByIPCServer(['node', 'cli', 'nocobase', 'subparent', 'testaa'])).toBeTruthy();
|
||||||
|
expect(app.cli.parseHandleByIPCServer(['node', 'cli', 'nocobase', 'subparent', 'testbb'])).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
41
packages/core/server/src/app-command.ts
Normal file
41
packages/core/server/src/app-command.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { Command } from 'commander';
|
||||||
|
|
||||||
|
export class AppCommand extends Command {
|
||||||
|
private _handleByIPCServer = false;
|
||||||
|
|
||||||
|
ipc() {
|
||||||
|
this._handleByIPCServer = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
isHandleByIPCServer() {
|
||||||
|
return this._handleByIPCServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
createCommand(name?: string): AppCommand {
|
||||||
|
return new AppCommand(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseHandleByIPCServer(argv, parseOptions?): Boolean {
|
||||||
|
//@ts-ignore
|
||||||
|
const userArgs = this._prepareUserArgs(argv, parseOptions);
|
||||||
|
|
||||||
|
if (userArgs[0] === 'nocobase') {
|
||||||
|
userArgs.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastCommand = this;
|
||||||
|
|
||||||
|
for (const arg of userArgs) {
|
||||||
|
// @ts-ignore
|
||||||
|
const subCommand = lastCommand._findCommand(arg);
|
||||||
|
if (subCommand) {
|
||||||
|
lastCommand = subCommand;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastCommand && lastCommand.isHandleByIPCServer();
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,7 @@ import { ApplicationVersion } from './helpers/application-version';
|
|||||||
import { Locale } from './locale';
|
import { Locale } from './locale';
|
||||||
import { Plugin } from './plugin';
|
import { Plugin } from './plugin';
|
||||||
import { InstallOptions, PluginManager } from './plugin-manager';
|
import { InstallOptions, PluginManager } from './plugin-manager';
|
||||||
|
import { AppCommand } from './app-command';
|
||||||
|
|
||||||
const packageJson = require('../package.json');
|
const packageJson = require('../package.json');
|
||||||
|
|
||||||
@ -163,7 +164,7 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
|||||||
return this._cache;
|
return this._cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _cli: Command;
|
protected _cli: AppCommand;
|
||||||
|
|
||||||
get cli() {
|
get cli() {
|
||||||
return this._cli;
|
return this._cli;
|
||||||
@ -286,7 +287,7 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
|||||||
return this.resourcer.registerActions(handlers);
|
return this.resourcer.registerActions(handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
command(name: string, desc?: string, opts?: CommandOptions): Command {
|
command(name: string, desc?: string, opts?: CommandOptions): AppCommand {
|
||||||
return this.cli.command(name, desc, opts).allowUnknownOption();
|
return this.cli.command(name, desc, opts).allowUnknownOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,7 +364,7 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
|||||||
}
|
}
|
||||||
|
|
||||||
createCli() {
|
createCli() {
|
||||||
const command = new Command('nocobase')
|
const command = new AppCommand('nocobase')
|
||||||
.usage('[command] [options]')
|
.usage('[command] [options]')
|
||||||
.hook('preAction', async (_, actionCommand) => {
|
.hook('preAction', async (_, actionCommand) => {
|
||||||
this._actionCommand = actionCommand;
|
this._actionCommand = actionCommand;
|
||||||
|
@ -3,6 +3,7 @@ import Application from '../application';
|
|||||||
export default (app: Application) => {
|
export default (app: Application) => {
|
||||||
app
|
app
|
||||||
.command('install')
|
.command('install')
|
||||||
|
.ipc()
|
||||||
.option('-f, --force')
|
.option('-f, --force')
|
||||||
.option('-c, --clean')
|
.option('-c, --clean')
|
||||||
.action(async (...cliArgs) => {
|
.action(async (...cliArgs) => {
|
||||||
|
@ -6,18 +6,19 @@ export default (app: Application) => {
|
|||||||
const pm = app.command('pm');
|
const pm = app.command('pm');
|
||||||
|
|
||||||
pm.command('create')
|
pm.command('create')
|
||||||
|
.ipc()
|
||||||
.arguments('plugin')
|
.arguments('plugin')
|
||||||
.action(async (plugin) => {
|
.action(async (plugin) => {
|
||||||
await app.pm.create(plugin);
|
await app.pm.create(plugin);
|
||||||
});
|
});
|
||||||
|
|
||||||
pm.command('add')
|
pm.command('add')
|
||||||
|
.ipc()
|
||||||
.argument('<pkg>')
|
.argument('<pkg>')
|
||||||
.option('--registry [registry]')
|
.option('--registry [registry]')
|
||||||
.option('--auth-token [authToken]')
|
.option('--auth-token [authToken]')
|
||||||
.option('--version [version]')
|
.option('--version [version]')
|
||||||
.action(async (name, options, cli) => {
|
.action(async (name, options, cli) => {
|
||||||
console.log('pm.add', name, options);
|
|
||||||
try {
|
try {
|
||||||
await app.pm.addViaCLI(name, _.cloneDeep(options));
|
await app.pm.addViaCLI(name, _.cloneDeep(options));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -26,6 +27,7 @@ export default (app: Application) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
pm.command('update')
|
pm.command('update')
|
||||||
|
.ipc()
|
||||||
.argument('<packageName>')
|
.argument('<packageName>')
|
||||||
.option('--path [path]')
|
.option('--path [path]')
|
||||||
.option('--url [url]')
|
.option('--url [url]')
|
||||||
@ -44,6 +46,7 @@ export default (app: Application) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
pm.command('enable')
|
pm.command('enable')
|
||||||
|
.ipc()
|
||||||
.arguments('<plugins...>')
|
.arguments('<plugins...>')
|
||||||
.action(async (plugins) => {
|
.action(async (plugins) => {
|
||||||
try {
|
try {
|
||||||
@ -54,6 +57,7 @@ export default (app: Application) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
pm.command('disable')
|
pm.command('disable')
|
||||||
|
.ipc()
|
||||||
.arguments('<plugins...>')
|
.arguments('<plugins...>')
|
||||||
.action(async (plugins) => {
|
.action(async (plugins) => {
|
||||||
try {
|
try {
|
||||||
@ -64,6 +68,7 @@ export default (app: Application) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
pm.command('remove')
|
pm.command('remove')
|
||||||
|
.ipc()
|
||||||
.arguments('<plugins...>')
|
.arguments('<plugins...>')
|
||||||
.action(async (plugins) => {
|
.action(async (plugins) => {
|
||||||
await app.pm.remove(plugins);
|
await app.pm.remove(plugins);
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import Application from '../application';
|
import Application from '../application';
|
||||||
|
|
||||||
export default (app: Application) => {
|
export default (app: Application) => {
|
||||||
app.command('restart').action(async (...cliArgs) => {
|
app
|
||||||
|
.command('restart')
|
||||||
|
.ipc()
|
||||||
|
.action(async (...cliArgs) => {
|
||||||
await app.restart({
|
await app.restart({
|
||||||
cliArgs,
|
cliArgs,
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import Application from '../application';
|
import Application from '../application';
|
||||||
|
|
||||||
export default (app: Application) => {
|
export default (app: Application) => {
|
||||||
app.command('stop').action(async (...cliArgs) => {
|
app
|
||||||
|
.command('stop')
|
||||||
|
.ipc()
|
||||||
|
.action(async (...cliArgs) => {
|
||||||
await app.stop({
|
await app.stop({
|
||||||
cliArgs,
|
cliArgs,
|
||||||
});
|
});
|
||||||
|
@ -5,7 +5,10 @@ import Application from '../application';
|
|||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
export default (app: Application) => {
|
export default (app: Application) => {
|
||||||
app.command('upgrade').action(async (...cliArgs) => {
|
app
|
||||||
|
.command('upgrade')
|
||||||
|
.ipc()
|
||||||
|
.action(async (...cliArgs) => {
|
||||||
const [opts] = cliArgs;
|
const [opts] = cliArgs;
|
||||||
console.log('upgrading...');
|
console.log('upgrading...');
|
||||||
await app.upgrade();
|
await app.upgrade();
|
||||||
|
@ -228,12 +228,14 @@ export class Gateway extends EventEmitter {
|
|||||||
ipcClient = await this.tryConnectToIPCServer();
|
ipcClient = await this.tryConnectToIPCServer();
|
||||||
|
|
||||||
if (ipcClient) {
|
if (ipcClient) {
|
||||||
await ipcClient.write({ type: 'passCliArgv', payload: { argv: process.argv } });
|
const response: any = await ipcClient.write({ type: 'passCliArgv', payload: { argv: process.argv } });
|
||||||
// should wait for server response
|
|
||||||
ipcClient.close();
|
ipcClient.close();
|
||||||
|
|
||||||
|
if (response.type !== 'error' || response.payload.message !== 'Not handle by ipc server') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isStart || !ipcClient) {
|
if (isStart || !ipcClient) {
|
||||||
await createStoragePluginsSymlink();
|
await createStoragePluginsSymlink();
|
||||||
|
@ -66,6 +66,14 @@ export class IPCSocketServer {
|
|||||||
const argv = payload.argv;
|
const argv = payload.argv;
|
||||||
|
|
||||||
const mainApp = await AppSupervisor.getInstance().getApp('main');
|
const mainApp = await AppSupervisor.getInstance().getApp('main');
|
||||||
|
const cli = mainApp.cli;
|
||||||
|
if (
|
||||||
|
!cli.parseHandleByIPCServer(argv, {
|
||||||
|
from: 'node',
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
throw new Error('Not handle by ipc server');
|
||||||
|
}
|
||||||
|
|
||||||
return mainApp.runAsCLI(argv, {
|
return mainApp.runAsCLI(argv, {
|
||||||
from: 'node',
|
from: 'node',
|
||||||
|
Loading…
Reference in New Issue
Block a user